Appearance
Getting started
Requirements
- PHP >= 8.2, extension
curldansodium - Ekstensi Phalcon 5 terpasang sebagai PHP extension (bukan lewat composer)
guzzlehttp/guzzle(^7.4) terpasang otomatis lewat composer — dipakaiCore\Auth\OAuth2\*/Core\Middleware\OAuth2Auth(client OAuth2/OIDC generik).Core\Auth\Casdoor\*/Core\Middleware\CasdoorAuthTIDAK butuh Guzzle sama sekali (tetap curl langsung) — lihat Casdoor & OAuth2/OIDC kalau cuma pakai Casdoor dan ingin tau kenapa dependency ini muncul di composer.lock Anda.- Opsional tergantung fitur yang dipakai:
ext-sqlsrv+ext-pdo_sqlsrv(adapter SQL Server),ext-redis/ext-memcached(adapter session/cache)
Instalasi
json
{
"repositories": [
{ "type": "vcs", "url": "git@git.aurorasystem.co.id:tirta-patriot/phoenix-core.git" }
],
"require": {
"tirta-patriot/phoenix-core": "^1.0"
}
}bash
composer require tirta-patriot/phoenix-coreHapus baris "Core\\": "system/" dari autoload.psr-4 project Anda (sudah datang dari package), lalu hapus folder system/ fisiknya kalau sebelumnya di-copy manual.
Install langsung dari branch (belum di-tag)
Buat coba perubahan yang belum dirilis sebagai tag (mis. fix/feature yang masih di main tapi belum di-git tag), pakai constraint dev-{nama-branch} alih-alih ^x.y:
json
{
"repositories": [
{ "type": "vcs", "url": "git@git.aurorasystem.co.id:tirta-patriot/phoenix-core.git" }
],
"require": {
"tirta-patriot/phoenix-core": "dev-main"
}
}bash
composer require tirta-patriot/phoenix-core:dev-mainGanti main dengan nama branch lain kalau perlu (mis. dev-fix/nama-branch). Jangan pakai ini di production — begitu branch-nya berubah (force-push, commit baru), composer update bisa menarik kode yang belum pernah direview sebagai rilis. Kunci ke tag (§ di atas) begitu perubahannya sudah di-tag.
Quick start
App baru cukup:
php
// public/index.php
require_once __DIR__ . '/../vendor/autoload.php';
Core\Kernel::boot()->run();Kernel::boot() (tanpa argumen) otomatis: registrasi ErrorHandler (strict default), deteksi BASEPATH lewat lokasi install package ini (Composer\InstalledVersions), Environment::boot() (muat .env, daftarkan helper env()/env_bool()), lalu TrustProxy::beforeExecute() (terjemahkan X-Forwarded-* dari app/config/trustproxy.php kalau ada, no-op kalau tidak) — urutan ini WAJIB persis begini: ErrorHandler duluan supaya error di Environment::boot() sendiri (.env malformed, dst) ikut tertangani rapi, bukan raw PHP fatal error yang bocorin full path/stack trace ke browser; TrustProxy sebelum request URI/baseURL dihitung, supaya app di belakang reverse proxy TLS-terminating tetap mendeteksi HTTPS dengan benar tanpa app perlu memanggil apa pun secara manual.
Kalau butuh kontrol eksplisit (mis. ErrorHandler::register(false) untuk app lama yang masih banyak warning laten, atau BASEPATH custom/tidak standar):
php
// public/index.php
define('BASEPATH', realpath(__DIR__ . '/..'));
require_once BASEPATH . '/vendor/autoload.php';
// Didaftarkan manual SEBELUM Kernel::boot() supaya menang — register()
// idempotent, panggilan pertama yang menang (lihat catatan di bawah).
Core\ErrorHandler::register(false);
Core\Kernel::boot(BASEPATH)->run();Environment::boot() aman dipanggil manual juga sebelum Kernel::boot() (idempotent, no-op kedua) — app lama yang sudah punya baris itu di public/index.php-nya TIDAK perlu diubah.
Core\Kernel::boot() otomatis mendaftarkan Core\DefaultServiceProvider, yang menyediakan service: config, crypt, request, response, cookies, router, security, url, filter, logger, eventsManager, dispatcher, session, db (+ db.{key} per koneksi tambahan), viewCache, dataCache, modelsManager, escaper, flash, annotations, registry, modelsMetadata, view, Hashids\Hashids::class.
Core\ErrorHandler::register() (opsional, tapi sangat disarankan) memasang set_error_handler/set_exception_handler/register_shutdown_function yang:
- Render halaman debug (
Phalcon\Support\Debug) kalauAPP_DEBUG=trueDANAPP_ENVbukanproduction— dua syarat sekaligus, supaya stack trace tidak pernah bocor di production meskiAPP_DEBUGketinggalantrue. - Respons JSON (
{error, message}, +tracekalau debug) untuk request AJAX (X-Requested-With: XMLHttpRequest) atauAccept: application/json. - Render lewat View/Volt kalau service
viewtersedia di DI — cariapp/views/Errors/notFound.volt(404),Errors/unauthorized.volt(401/403),Errors/error{code}.volt(kalau ada), fallbackErrors/error500.volt. Kalau app belum punya file.voltyang cocok sama sekali, jatuh ke HTML generik bawaan — dicek pakaifile_exists()dulu, bukan cuma andalkan try/catch, karenaPhalcon\Mvc\View::render()TIDAK throw kalau file target tidak ada (cuma balikin content kosong), jadi tanpa cek ini response bisa 500 dengan body benar-benar kosong. - Exception
Phalcon\(Mvc\)Dispatcher\Exception(route/controller/action tidak ketemu) otomatis dipetakan ke 404, bukan 500. - Aman didaftarkan SEBELUM
Environment::boot()(lihat urutan di atas) —isDebugMode()fallback kegetenv()mentah kalau helperenv()/env_bool()belum ke-load, jadi error diEnvironment::boot()sendiri (.envmalformed, dst) tetap tertangani rapi, bukan raw PHP fatal error yang bocorin full path server + stack trace ke browser.
register(bool $throwOnWarnings = true) — parameter opsional untuk app existing/legacy yang punya banyak warning laten (undefined variable/array key, dst) yang selama ini diam-diam ditoleransi PHP:
php
Core\ErrorHandler::register(false); // lenient: warning cuma di-error_log(), TIDAK 500-in page- Default
true(strict) —E_WARNING/E_NOTICE/E_DEPRECATEDdkk langsung jadiErrorExceptionyang menghentikan request. Cocok untuk app baru/bersih — bug ketahuan sesegera mungkin. false(lenient) — level di atas cuma di-error_log(), request lanjut jalan seperti PHP klasik.E_RECOVERABLE_ERRORdanE_USER_ERROR(fatal eksplisit lewattrigger_error(..., E_USER_ERROR)) tetap fatal apa pun nilai parameter ini — dua level itu bukan "gaya kode lama", tapi indikasi state sudah rusak.register()idempotent — panggilan PERTAMA yang menang, panggilan berikutnya jadi no-op (termasuk parameternya diabaikan). Ini WAJIB tahu:Core\Kernel::boot()sendiri memanggilErrorHandler::register()tanpa argumen sebagai fallback default untuk app yang belum sempat register manual. Karena idempotent, app yang sudah panggilregister(false)lebih dulu (lihat urutan Quick start di atas) TIDAK akan ketimpa balik ke strict oleh panggilan fallback Kernel itu — tapi kalau urutannya kebalik (Kernel jalan duluan sebelum app sempat register), app kehilangan kontrol parameter ini sama sekali. Bug nyata ini pernah kejadian:register(false)dipublic/index.phpterlihat tidak berefek sampai ketemu akar masalahnya.