Config Cache
php artisan config:cache mengompilasi seluruh file konfigurasi menjadi satu array PHP dan setelah itu Laravel tidak lagi membaca file config satu per satu. PandaBear kompatibel dengan mekanisme ini tanpa perlakuan khusus — package tidak memanggil env() di luar file config, dan config/panda-panel.php tidak menyimpan Closure. Halaman ini menjelaskan config apa yang dibaca PandaBear, kapan config tersebut dibaca, dan dua kondisi yang masih dapat mengejutkan ketika config sudah dicache.
Contoh minimal yang berfungsi
php artisan config:cacheAtau sebagai bagian dari optimasi lengkap:
php artisan optimize # config, routes, events, views — dan panel:cachePastikan Panel tetap dapat di-resolve setelah caching:
php artisan config:show panda-panel
php artisan route:list --path=admin2
Config yang dibaca PandaBear
Hanya ada dua namespace config yang dibaca.
panda-panel.*
| Key | Default | Dibaca oleh | Kapan |
|---|---|---|---|
panels | [] | PandaPanelServiceProvider::configuredPanels() | boot |
register_routes | true | registerRoutes() | boot |
register_web_middleware | true | registerMiddleware() | boot |
register_guest_redirect | true | registerGuestRedirect() | boot |
load_migrations | true | registerMigrations() | boot |
home_redirect.enabled | true | PandaPanel\Support\PanelHomeRedirect | setiap request |
home_redirect.paths | ['dashboard'] | sama | setiap request |
integrations.allowed_hosts | [] | PandaPanel\Integrations\OutboundUrl | saat save dan sebelum setiap outbound request |
integrations.block_private_networks | true | sama | sama |
integrations.history.enabled | true | PanelIntegrationDelivery::enabled() | setelah setiap delivery |
integrations.history.keep_per_integration | 50 | PanelIntegrationDelivery::prune() | setelah setiap delivery |
integrations.history.retention_days | 30 | sama | sama |
frontend.panel_path | 'js/panel' | PandaPanel\Support\FrontendPaths::panel() | publish, generator, panel:icons |
frontend.pages_path | 'js/pages/Panels' | FrontendPaths::pages() | sama |
Config bawaan Laravel
| Key | Dibaca oleh | Untuk |
|---|---|---|
broadcasting.default | PandaPanel\Support\BroadcastSupport::isConfigured() | menentukan apakah channel realtime boleh dibagikan ke frontend |
broadcasting.connections.{default}.driver | sama | driver null dan log dianggap tidak memiliki broadcaster yang dapat disubscribe |
app.name | PandaPanel\Core\Panel::getBrandName() | fallback brand name jika Panel tidak memanggil brandName() |
Tidak ada config lain. PandaBear juga tidak mendefinisikan environment variable khusus seperti PANDA_*, karena seluruh setting package ditulis sebagai literal di file config, bukan memanggil env() secara langsung di runtime.
Mengapa PandaBear aman digunakan dengan config:cache
Ada tiga karakteristik yang menghindari masalah klasik package saat config dicache.
Tidak ada Closure di file config
config:cache menggunakan var_export() terhadap seluruh merged config. Closure di dalam config menyebabkan Laravel melempar:
LogicException: Your configuration files are not serializableconfig/panda-panel.php hanya berisi scalar, array string, dan ::class constant. ::class sudah berubah menjadi string saat file config dievaluasi.
// config/panda-panel.php
'panels' => [
App\Panels\Admin\AdminPanelProvider::class, // sudah berupa string saat dicache
],2
3
4
Tidak ada env() di luar config
Ketika configuration sudah dicache, Laravel tidak membaca ulang .env. Package yang memanggil env() dari service atau controller sering bekerja di development tetapi menghasilkan null di production.
PandaBear tidak melakukan itu. Semua runtime read menggunakan:
config()
Config::get()2
Nested config read memiliki fallback default
Published config yang dibuat dengan versi package lama tetap dapat bekerja ketika versi baru menambah nested key:
Config::get('panda-panel.integrations.history.keep_per_integration', 50);
Config::get('panda-panel.integrations.block_private_networks', true);
config('panda-panel.home_redirect', []);2
3
Hal ini penting karena mergeConfigFrom() hanya membantu pada top-level merge. Empat boot switch top-level dibaca tanpa fallback — misalnya get('panda-panel.register_routes') !== true — dan aman karena top-level key yang hilang akan ditambahkan package defaults saat merge.
Kombinasi tersebut memungkinkan application meng-upgrade PandaBear tanpa harus selalu re-publish config file.
Gotcha: merge config bersifat shallow
Provider menggabungkan default package di bawah config application:
// PandaPanelServiceProvider::register()
$this->mergeConfigFrom($this->packagePath('config/panda-panel.php'), 'panda-panel');2
mergeConfigFrom() Laravel menggunakan top-level array_merge. Jadi published config yang mendefinisikan block integrations akan menggantikan seluruh default block integrations, bukan melakukan deep merge per-key.
Jika published file lama tidak memiliki:
integrations.history.retention_daysmaka merged config memang tidak memiliki key tersebut. PandaBear tetap aman karena tempat yang membacanya memberikan fallback default.
Tetapi developer tetap perlu memahami bahwa published config adalah file milik application yang harus dipelihara. File tersebut tidak otomatis memperoleh nested key baru setiap kali package di-upgrade.
Dua konsekuensi deployment:
- Publish config bersifat optional. Jika tidak dipublish,
mergeConfigFrom()memberikan semua default danconfig:cachemenyimpannya.mergeConfigFrom()memang tidak berjalan jika config sudah cached, tetapi prosesconfig:cachesendiri melakukan boot application terlebih dahulu, sehingga hasil merge-lah yang ditulis ke cache. - Setelah upgrade package, bandingkan published config dengan
vendor/chocoalano/panel/config/panda-panel.php. Nested key baru tidak muncul otomatis.
Mendaftarkan Panel ketika config dicache
panels adalah ordered list dari provider class:
// config/panda-panel.php
'panels' => [
App\Panels\Admin\AdminPanelProvider::class,
App\Panels\App\AppPanelProvider::class,
],2
3
4
5
Urutan ini juga memengaruhi Panel pertama yang dipilih ketika sebuah request membutuhkan destination Panel tetapi tidak menunjuk Panel tertentu.
Class name yang tidak dapat di-resolve dilewati daripada membuat boot application fatal:
foreach ($configured as $provider) {
if (is_string($provider) && is_subclass_of($provider, PanelProvider::class)) {
$panels[] = $provider;
}
}2
3
4
5
Fatal pada fase ini terjadi sebelum route mana pun tersedia, termasuk route yang mungkin membantu developer melihat error. Dengan melewati entry invalid, application tetap dapat boot. Ketidaksesuaian kemudian terlihat dari output panel:cache karena jumlah Panel lebih sedikit dari yang diharapkan.
PandaPanel\Support\Installer\PanelRegistrar digunakan panel:install untuk menambahkan provider ke config:
use PandaPanel\Support\Installer\PanelRegistrar;
PanelRegistrar::register(App\Panels\Admin\AdminPanelProvider::class);
// static register(string $provider, ?string $path = null): string2
3
4
| Return | Arti |
|---|---|
PanelRegistrar::REGISTERED | provider berhasil ditambahkan |
PanelRegistrar::ALREADY_PRESENT | provider sudah ada |
PanelRegistrar::NO_CONFIG | config/panda-panel.php belum dipublish |
PanelRegistrar::UNRECOGNISED | struktur block panels tidak dikenali, sehingga file tidak diubah |
Registrar mengedit file, jadi ini adalah proses instalasi, bukan deploy. Pada server yang sudah menggunakan config cache, perubahan file tidak aktif sampai config cache dibangun ulang.
Mematikan boot-time switch
Empat switch dibaca satu kali saat boot dan memungkinkan application mengambil alih behavior default package:
// config/panda-panel.php
'register_routes' => false, // application mendaftarkan route group Panel sendiri
'register_web_middleware' => false, // application memasang ResetPanelContext / ShareFlashToast sendiri
'register_guest_redirect' => false, // application memanggil redirectGuestsTo() sendiri
'load_migrations' => false, // migration sudah dipublish dan dimiliki application2
3
4
5
Masing-masing dibahas lebih rinci pada:
register_web_middleware => false memiliki konsekuensi production yang sangat penting. ResetPanelContext membersihkan current Panel di awal setiap web request. Jika middleware tersebut dimatikan dan application tidak memasangnya sendiri, state Panel dapat terbawa dari request sebelumnya ketika menggunakan long-lived worker seperti Octane. Lihat Octane.
Membersihkan config cache
php artisan config:clear
php artisan optimize:clear # config, routes, views, events — dan panel:clear2
Rollback yang masih memakai config cache dari release yang lebih baru memiliki kelas masalah yang sama seperti bootstrap/cache yang dishare antar-release. Lihat Rollbacks.
Hal yang perlu diperhatikan
config:cachemembekukan.env. Ini behavior Laravel dan berlaku juga untukBROADCAST_CONNECTION,QUEUE_CONNECTION, dan variable lain. Setelah mengubahnya, rebuild config cache.- Published config tidak otomatis memperoleh key baru ketika upgrade. Diff terhadap config package setelah upgrade.
mergeConfigFrom()hanya melakukan top-level merge. Mendefinisikanintegrationspada application menggantikan seluruh block defaultintegrations.- Panel provider yang tidak dapat di-resolve dari
panelsdilewati secara senyap. Output count daripanel:cachemenjadi indikatornya. config:cacheberbeda daripanel:cache. Keduanya merupakan cache berbeda dan keduanya dijalankan olehoptimize.- Resolved metadata Panel tidak disimpan di config cache. Class manifest berada pada file sendiri, dan data runtime tidak dicache di config.