symplify/amnesia
Provides PHP constant wrappers for Symfony configuration keys to replace typo-prone strings in PHP config files. Covers common extensions like Framework, Twig, Doctrine and Routing, making config safer, more discoverable, and easier to refactor.
Installation:
composer require symplify/amnesia
Note: Only use this for legacy Laravel/Symfony <5.3 projects where upgrading is not immediately feasible.
First Use Case:
Replace a hardcoded Symfony extension configuration (e.g., framework.yaml) with PHP constants for type safety and IDE autocompletion.
Example:
use Symplify\Amnesia\ValueObject\Symfony\Extension\FrameworkExtension;
$containerConfigurator->extension(FrameworkExtension::NAME, [
FrameworkExtension::SECRET => env('APP_SECRET'),
]);
Where to Look First:
Symplify\Amnesia\ValueObject\Symfony\Extension for pre-defined constants (e.g., FrameworkExtension, DoctrineExtension).Symplify\Amnesia\Functions for helper functions like env().Symfony Extension Configuration:
ContainerConfigurator calls.// Before (YAML)
framework:
secret: '%env(APP_SECRET)%'
// After (PHP)
$containerConfigurator->extension(FrameworkExtension::NAME, [
FrameworkExtension::SECRET => env('APP_SECRET'),
]);
Routing Configuration:
RoutingConfigurator for annotation-based routes:
$routes->import(__DIR__ . '/../src/Controller', Routing::TYPE_ANNOTATION);
Doctrine Configuration:
$containerConfigurator->extension(DoctrineExtension::NAME, [
DoctrineExtension::DBAL => [
DBAL::HOST => env('DATABASE_HOST'),
// ...
],
]);
Legacy Migration:
config/packages/ or config/bundles.php.Amnesia constants in a config.php file using ContainerConfigurator.ConfigBuilder or Laravel-native alternatives.Environment-Aware Configs:
env() helper to inject .env variables:
$containerConfigurator->extension(FrameworkExtension::NAME, [
FrameworkExtension::SECRET => env('APP_SECRET'),
FrameworkExtension::DEBUG => env('APP_DEBUG', 'prod') === 'dev',
]);
Twig Integration:
$containerConfigurator->extension(TwigExtension::NAME, [
TwigExtension::GLOBALS => ['site_title' => 'MyApp'],
TwigExtension::NUMBER_FORMAT => [NumberFormat::DECIMALS => 2],
]);
Laravel-Symfony Bridge:
Symfony\Component\DependencyInjection\ContainerBuilder alongside Laravel’s container.$symfonyContainer = new ContainerBuilder();
$loader = new ContainerConfigurator($symfonyContainer);
// Use Amnesia helpers here...
Service Provider Integration:
register() method:
public function register()
{
$container = $this->app->make('service_container');
$symfonyContainer = new ContainerBuilder();
$loader = new ContainerConfigurator($symfonyContainer);
// Configure with Amnesia...
$this->app->singleton('symfony.container', fn() => $symfonyContainer);
}
Testing:
ContainerConfigurator in PHPUnit:
$container = $this->createMock(ContainerBuilder::class);
$loader = new ContainerConfigurator($container);
Deprecated Status:
ConfigBuilder or Laravel-native solutions.Symfony Dependency:
ContainerBuilder, which Laravel does not natively support.IDE Autocompletion:
FrameworkExtension::SECRET) may not auto-complete in older PHPStorm/Laravel IDE Helper versions.@property annotations.Environment Variables:
env() helper may not resolve Laravel’s .env files by default.Symplify\Amnesia\Functions\env() is patched to use Laravel’s env() or config() helpers.Configuration Overrides:
APP_DEBUG).config() values:
if (config('app.debug') !== true) {
$containerConfigurator->extension(FrameworkExtension::NAME, [
FrameworkExtension::DEBUG => false,
]);
}
Container Dumping:
$symfonyContainer->compile();
file_put_contents(
storage_path('logs/symfony_container.php'),
'<?php return ' . var_export($symfonyContainer->getParameterBag()->all(), true) . ';'
);
Parameter Conflicts:
ParameterNotFoundException if a required parameter (e.g., DATABASE_HOST) is missing..env or Symfony’s ParameterBag:
$symfonyContainer->getParameter('database_host'); // Throws exception if missing
Routing Issues:
TYPE_ANNOTATION.FrameworkBundle and paths are correct:
$routes->import(__DIR__ . '/../../src/Controller', Routing::TYPE_ANNOTATION);
Case Sensitivity:
FrameworkExtension::NAME vs. framework).$containerConfigurator->extension(FrameworkExtension::NAME, [...]); // Correct
$containerConfigurator->extension('framework', [...]); // May fail
Default Values:
TwigExtension) require all nested keys to be defined.// Correct:
$containerConfigurator->extension(TwigExtension::NAME, [
TwigExtension::NUMBER_FORMAT => [
NumberFormat::DECIMALS => 2,
NumberFormat::DECIMAL_POINT => '.',
],
]);
Circular Dependencies:
ContainerConfigurator::services().Custom Extensions:
Symplify\Amnesia\ValueObject\Symfony\Extension\AbstractExtension to add new constants.namespace App\Amnesia\Extension;
use Symplify\Amnesia\ValueObject\Symfony\Extension\AbstractExtension;
class AppExtension extends AbstractExtension
{
public const NAME = 'app';
public const TIMEZONE = 'timezone';
}
Environment Helpers:
Symplify\Amnesia\Functions\env() with Laravel’s env():
if (!function_exists('Symplify\Amnesia\Functions\env')) {
function env(string $key, $default = null): string
{
return \Illuminate\Support\Env::get($key, $default);
}
}
Container Integration:
$laravelContainer = $this->app;
$symfonyContainer = new ContainerBuilder();
// Load Amnesia configs into $symfonyContainer...
$laravelContainer->instance('symfony.container', $symfonyContainer);
How can I help you explore Laravel packages today?