Symfony 7.4 is a minor release. According to the Symfony release process, there should be no significant
backward compatibility breaks. Minor backward compatibility breaks are prefixed in this document with
[BC BREAK], make sure your code is compatible with these entries before upgrading.
Read more about this in the Symfony documentation.
If you're upgrading from a version below 7.3, follow the 7.3 upgrade guide first.
- Deprecate
AbstractBrowser::useHtml5Parser(); Symfony 8 will unconditionally use the native HTML5 parser - Add
AbstractBrowser::wrapContent()method to wrap response content and give proper context when fetching fragments
- Bump ext-redis to 6.1 and ext-relay to 0.11 minimum
- Deprecate accessing the internal scope of the loader in PHP config files, use only its public API instead
- Deprecate setting a default value to a node that is required, and vice versa
- Deprecate fluent config builders, return PHP arrays from your config instead
- Deprecate
Symfony\Component\Console\Application::add()in favor ofaddCommand()
- [BC BREAK] Throw when using
$thisor its internal scope from PHP config files; use the$loadervariable instead - Add argument
$targettoContainerBuilder::registerAliasForArgument() - Add argument
$throwOnAbstracttoContainerBuilder::findTaggedResourceIds() - Deprecate registering a service without a class when its id is a non-existing FQCN
- Deprecate XML configuration format, use YAML or PHP instead
- Deprecate
ExtensionInterface::getXsdValidationBasePath()andgetNamespace(); bundles that need to support older versions of Symfony can keep the methods but need to add the@deprecatedannotation on them - Deprecate the fluent PHP format for semantic configuration, use
$container->extension()or return an array instead-return function (AcmeConfig $config) { - $config->color('red'); -} +return App::config([ + 'acme' => [ + 'color' => 'red', + ], +]);
- Deprecate
UniqueEntity::getRequiredOptions()andUniqueEntity::getDefaultOption() - Deprecate the
AbstractDoctrineExtensionclass; its code is incorporated into the extension classes of Doctrine bundles
- Disabling HTML5 parsing is deprecated; Symfony 8 will unconditionally use the native HTML5 parser
- [BC BREAK] The
CurrencyTypereturns only the currencies that are active and recognized as legal tender for the current date; set theactive_at, andlegal_tenderoptions tonullto list all currencies no matter their current state
- Deprecate
Symfony\Bundle\FrameworkBundle\Console\Application::add()in favor ofaddCommand() - Deprecate
Symfony\Bundle\FrameworkBundle\Command\WorkflowDumpCommandin favor ofSymfony\Component\Workflow\Command\WorkflowDumpCommand
- Use the native HTML5 parser when using PHP 8.4+
- Deprecate
MastermindsParser; useNativeParserinstead - [BC BREAK]
ParserInterface::parse()can now return\Dom\Node|\DOMNode|nullinstead of just\DOMNode|null - Add argument
$contexttoParserInterface::parse()
- Deprecate using amphp/http-client < 5
- Deprecate passing an instance of
StoreInterfaceas$cacheargument toCachingHttpClientconstructor
- Add argument
$subtypeFallbacktoRequest::getFormat() - Deprecate using
Request::sendHeaders()after headers have already been sent; use aStreamedResponseinstead - Deprecate method
Request::get(), use properties->attributes,queryorrequestdirectly instead - Deprecate HTTP method override for methods GET, HEAD, CONNECT and TRACE; it will be ignored in Symfony 8.0
- Deprecate accepting null
$formatargument toRequest::setFormat()
- Deprecate implementing
__sleep/wakeup()on kernels; use__(un)serialize()instead - Deprecate implementing
__sleep/wakeup()on data collectors; use__(un)serialize()instead - Make
Profilefinal andProfiler::__sleep()internal
- Deprecate
PropertyMetadata::$streamToNativeValueTransformers, usePropertyMetadata::$valueTransformersinstead - Deprecate
PropertyMetadata::getNativeToStreamValueTransformer()andPropertyMetadata::getStreamToNativeValueTransformers(), usePropertyMetadata::getValueTransformers()instead - Deprecate
PropertyMetadata::withNativeToStreamValueTransformers()andPropertyMetadata::withStreamToNativeValueTransformers(), usePropertyMetadata::withValueTransformers()instead - Deprecate
PropertyMetadata::withAdditionalNativeToStreamValueTransformer()andPropertyMetadata::withAdditionalStreamToNativeValueTransformer, usePropertyMetadata::withAdditionalValueTransformer()instead
- Deprecate implementing
__sleep/wakeup()onAbstractPartimplementations; use__(un)serialize()instead
- Deprecate class
NotFoundActivationStrategy, useHttpCodeActivationStrategyinstead
- Deprecate class aliases in the
Annotationnamespace, use attributes instead - Deprecate getters and setters in attribute classes in favor of public properties
- Deprecate accessing the internal scope of the loader in PHP config files, use only its public API instead
- Deprecate XML configuration format, use YAML, PHP or attributes instead
-
Deprecate extending the
RememberMeDetailsclass with a constructor expecting the user FQCNBefore:
class CustomRememberMeDetails extends RememberMeDetails { public function __construct(string $userFqcn, string $userIdentifier, int $expires, string $value) { parent::__construct($userFqcn, $userIdentifier, $expires, $value); } }
After:
class CustomRememberMeDetails extends RememberMeDetails { public function __construct(string $userIdentifier, int $expires, string $value) { parent::__construct($userIdentifier, $expires, $value); } }
-
Deprecate callable firewall listeners, extend
AbstractListeneror implementFirewallListenerInterfaceinstead -
Deprecate
AbstractListener::__invoke -
Deprecate
LazyFirewallContext::__invoke() -
Deprecate
PersistentTokenInterface::getClass()andRememberMeDetails::getUserFqcn(), the user FQCN will be removed from the remember-me cookie in 8.0 -
Add argument
$accessDecisiontoAccessDecisionStrategyInterface::decide();
- Make
AttributeMetadataandClassMetadatafinal - Deprecate class aliases in the
Annotationnamespace, use attributes instead - Deprecate getters in attribute classes in favor of public properties
- Deprecate
ClassMetadataFactoryCompiler
- Deprecate implementing
__sleep/wakeup()on string implementations
- Deprecate
TranslatableMessage::__toString
- Deprecate setting the
exception_controllerconfig tonull. This was a legacy opt-out of a deprecation that is a no-op since Symfony 5.0. Remove that setting entirely instead.
- Default to
UuidV7when usingUuidFactory
-
Deprecate handling associative arrays in
GroupSequenceBefore
$groupSequence = GroupSequence(['value' => ['group 1', 'group 2']]);
After
$groupSequence = GroupSequence(['group 1', 'group 2']);
-
Deprecate configuring constraint options implicitly with the XML format
Before
<class name="Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity"> <constraint name="Callback"> <value>Symfony\Component\Validator\Tests\Fixtures\CallbackClass</value> <value>callback</value> </constraint> </class>
After
<class name="Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity"> <constraint name="Callback"> <option name="callback"> <value>Symfony\Component\Validator\Tests\Fixtures\CallbackClass</value> <value>callback</value> </option> </constraint> </class>
-
Deprecate configuring constraint options implicitly with the YAML format
Before
Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity: constraints: - Callback: validateMeStatic - Callback: [Symfony\Component\Validator\Tests\Fixtures\CallbackClass, callback]
After
Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity: constraints: - Callback: callback: validateMeStatic - Callback: callback: [Symfony\Component\Validator\Tests\Fixtures\CallbackClass, callback]
-
Deprecate implementing
__sleep/wakeup()onGenericMetadataimplementations; use__(un)serialize()instead -
Deprecate passing a list of choices to the first argument of the
Choiceconstraint. Use thechoicesoption instead -
Deprecate
getRequiredOptions()andgetDefaultOption()methods of theAll,AtLeastOneOf,CardScheme,Collection,CssColor,Expression,Regex,Sequentially,Type, andWhenconstraints -
Deprecate evaluating options in the base
Constraintclass. Initialize properties in the constructor of the concrete constraint class insteadBefore
class CustomConstraint extends Constraint { public $option1; public $option2; public function __construct(?array $options = null) { parent::__construct($options); } }
After
use Symfony\Component\Validator\Attribute\HasNamedArguments; class CustomConstraint extends Constraint { #[HasNamedArguments] public function __construct( public $option1 = null, public $option2 = null, ?array $groups = null, mixed $payload = null, ) { parent::__construct(null, $groups, $payload); } }
-
Deprecate the
getRequiredOptions()method of the baseConstraintclass. Use mandatory constructor arguments insteadBefore
class CustomConstraint extends Constraint { public $option1; public $option2; public function __construct(?array $options = null) { parent::__construct($options); } public function getRequiredOptions() { return ['option1']; } }
After
use Symfony\Component\Validator\Attribute\HasNamedArguments; class CustomConstraint extends Constraint { #[HasNamedArguments] public function __construct( public $option1, public $option2 = null, ?array $groups = null, mixed $payload = null, ) { parent::__construct(null, $groups, $payload); } }
-
Deprecate the
normalizeOptions()andgetDefaultOption()methods of the baseConstraintclass without replacements; overriding them in child constraint will not have any effects starting with Symfony 8.0 -
Deprecate passing an array of options to the
Compositeconstraint class. Initialize the properties referenced withgetNestedConstraints()in child classes before calling the constructor ofCompositeBefore
class CustomCompositeConstraint extends Composite { public array $constraints = []; public function __construct(?array $options = null) { parent::__construct($options); } protected function getCompositeOption(): string { return 'constraints'; } }
After
use Symfony\Component\Validator\Attribute\HasNamedArguments; class CustomCompositeConstraint extends Composite { #[HasNamedArguments] public function __construct( public array $constraints, ?array $groups = null, mixed $payload = null) { parent::__construct(null, $groups, $payload); } }