Symfony 7.4: Introducing Modernized PHP Configuration with Array Shapes
Symfony 7.4 deprecates fluent PHP config builders, introducing an array-based format with dynamic array shapes. This brings enhanced autocompletion, static analysis, and type validation.
Symfony 7.4 is backed by:
- redirection.io logs all your website’s HTTP traffic, and lets you fix errors with redirect rules in seconds. Give your marketing, SEO, and IT teams the right tool to manage your website traffic efficiently!
- As the creator of Symfony, SensioLabs supports companies using Symfony with an offering encompassing consultancy, expertise, services, training, and technical assistance to ensure the success of web application development projects.
- Private Packagist is a fast, reliable, and secure Composer repository for your private packages. It mirrors all your open-source dependencies for better availability and monitors them for security vulnerabilities.
- JoliCode is a team of passionate developers and open-source lovers, with strong expertise in PHP & Symfony technologies. They can help you build your projects using state-of-the-art practices.
Back in Symfony 5.3 (released in May 2021), we introduced config builder classes as a fluent PHP interface for configuring Symfony applications. These classes were dynamically generated based on installed bundles, enabling configuration like this:
// config/packages/security.php
use Symfony\Config\SecurityConfig;
return static function (SecurityConfig $security) {
$security->firewall('main')
->pattern('^/*')
->lazy(true)
->anonymous();
$security->accessControl([
'path' => '^/admin',
'roles' => 'ROLE_ADMIN'
]);
};
In Symfony 7.4, as part of a broader effort to modernize configuration formats (and coinciding with the deprecation of the XML configuration format), we are also deprecating the config builder classes and the fluent PHP configuration.
The primary technical reason for this change is that fluent configuration isn't flexible enough; it must strictly match a single canonical interpretation of the semantic configuration tree. It also significantly complicates automatic configuration updates via Symfony recipes.
So, what's replacing the fluent format? We're introducing a new array-based PHP configuration format. The previous example now transforms into:
// config/packages/security.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
return App::config([
'security' => [
// ...
'firewalls' => [
'main' => [
'pattern' => '^/*',
'lazy' => true,
'anonymous' => true,
],
],
'access_control' => [
[
'path' => '^/admin',
'roles' => 'ROLE_ADMIN'
],
],
]
]);
While this might initially appear to be "just arrays," there's significantly more to it. To truly enhance this new format, Symfony now defines array shapes for all configurations. These PHP metadata definitions can be read and processed by tools such as PhpStorm, PHPStan, and Psalm. This brings a host of benefits:
- Full autocompletion
- Static analysis
- Type validation
- Instant discoverability of every configuration option
These are not ordinary arrays; they combine the readability and familiarity of YAML with the powerful tooling advantages of native PHP.
These array shapes are dynamically generated based on the bundles installed in your application. The generated file, reference.php, is stored in the config/ directory. You should commit it to your repository and optionally add an entry in the autoload section of composer.json (e.g., "classmap": ["config/"]).
We are not yet ready to make this new format the universally recommended one, as YAML still offers many advantages. However, this update marks a significant step towards establishing PHP as a first-class configuration format in the future. The new approach is concise, expressive, easy to maintain, well-supported by modern tools, and leverages the full power of PHP. What's still needed? Not all static analyzers and IDEs fully support complex array shapes yet, Symfony Flex currently understands YAML only, and a few other pieces require refinement before this vision becomes a complete reality. Nevertheless, this is an exciting move toward a more unified, powerful, and developer-friendly configuration experience in Symfony.