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
- Bump ext-redis to 6.2 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
Symfony\Component\Console\Application::add()in favor ofaddCommand()
- Add argument
$targettoContainerBuilder::registerAliasForArgument() - Add argument
$throwOnAbstracttoContainerBuilder::findTaggedResourceIds() - Deprecate registering a service without a class when its id is a non-existing FQCN
- Deprecate using
$thisor its internal scope from PHP config files; use the$loadervariable instead - 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
UniqueEntity::getRequiredOptions()andUniqueEntity::getDefaultOption()
- 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 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 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
- 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); } }