A Symfony bundle that stores application configuration as key-value pairs in the database, with an EasyAdmin management interface, Twig/PHP accessors, and production deployment tooling.
- Key-value config entries stored in the database (
site_configtable) - EasyAdmin CRUD interface to manage values
- SQL export button for production deployment
- Twig and PHP service to read values anywhere
- 1-hour cache with automatic invalidation on change
composer require c975l/config-bundleRun the database migration to create the site_config table:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrateCreate a config/configs.json file in your bundle. Each entry will be inserted into the database on first load (duplicates are skipped):
[
{
"label": "Site Name",
"slug": "site-name",
"sensitive": false,
"value": null,
"kind": "text",
"description": "Name of the website"
},
{
"label": "Stripe Secret Key",
"slug": "stripe-secret-key",
"sensitive": true,
"value": null,
"kind": "text",
"description": "Stripe secret key (sk_live_...)"
}
]Valid kind values: text, html, image, code, bool, int.
Set sensitive: true for any entry that holds secrets (API keys, passwords, etc.).
Auto-discovers every vendor/c975l/*/config/configs.json file and loads them in one shot:
php bin/console c975l:config:load-allThe bundle registers a management dashboard at /management. Navigate to Config to view, create, edit, or delete entries.
On the config list page, click the Export SQL button. The browser downloads a site_config_YYYYMMDD_HHMMSS.sql file — nothing is written to disk or version control.
Import it on your production server:
mysql -u user -p dbname < site_config_20260626_120000.sqlBehavior per entry type:
is_sensitive |
SQL statement | Effect on production |
|---|---|---|
false |
INSERT … ON DUPLICATE KEY UPDATE |
Creates or updates label, value, kind, description |
true |
INSERT IGNORE INTO |
Creates if missing; preserves existing production value |
This means non-sensitive values (labels, descriptions, default content) are kept in sync, while live API keys and secrets already set on production are never overwritten.
use c975L\ConfigBundle\Service\ConfigServiceInterface;
class MyService
{
public function __construct(
private readonly ConfigServiceInterface $configService,
) {}
public function doSomething(): void
{
$siteName = $this->configService->get('site-name');
$isEnabled = $this->configService->getBool($this->configService->get('feature-enabled'));
$env = $this->configService->getContainerParameter('kernel.environment');
}
}{# Read from database #}
{{ config('site-name') }}
{# Read from Symfony container parameters #}
{{ configParam('kernel.environment') }}MIT — see LICENSE.