You are browsing the Symfony 4 documentation, which changes significantly from Symfony 3.x. If your app doesn't use Symfony 4 yet, browse the Symfony 3.4 documentation.
The Coding Standards document describes the coding standards for the Symfony projects and the internal and third-party bundles. This document describes coding standards and conventions used in the core framework to make it more consistent and predictable. You are encouraged to follow them in your own code, but you don't need to.
When an object has a "main" many relation with related "things" (objects, parameters, ...), the method names are normalized:
The usage of these methods is only allowed when it is clear that there is a main relation:
- a Service
Containerhas many services and many parameters (as services is the main relation, the naming convention is used for this relation);
- a Console
Inputhas many arguments and many options. There is no "main" relation, and so the naming convention does not apply.
For many relations where the convention does not apply, the following methods
must be used instead (where
XXX is the name of the related thing):
|Main Relation||Other Relations|
While "setXXX" and "replaceXXX" are very similar, there is one notable difference: "setXXX" may replace, or add new elements to the relation. "replaceXXX", on the other hand, cannot add new elements. If an unrecognized key is passed to "replaceXXX" it must throw an exception.
From time to time, some classes and/or methods are deprecated in the framework; that happens when a feature implementation cannot be changed because of backward compatibility issues, but we still want to propose a "better" alternative. In that case, the old implementation can be deprecated.
Deprecations must only be introduced on the next minor version of the impacted component (or bundle, or bridge, or contract). They can exceptionally be introduced on previous supported versions if they are critical.
A new class (or interface, or trait) cannot be introduced as deprecated, or contain deprecated methods.
A new method cannot be introduced as deprecated.
A feature is marked as deprecated by adding a
@deprecated phpdoc to
relevant classes, methods, properties, ...:
/** * @deprecated since Symfony 2.8. */
The deprecation message must indicate the version in which the feature was deprecated, and whenever possible, how it was replaced:
/** * @deprecated since Symfony 2.8, use Replacement instead. */
When the replacement is in another namespace than the deprecated class, its FQCN must be used:
/** * @deprecated since Symfony 2.8, use A\B\Replacement instead. */
E_USER_DEPRECATED error must also be triggered to help people with the migration:
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 2.8, use "%s" instead.', Deprecated::class, Replacement::class), E_USER_DEPRECATED);
Without the @-silencing operator, users would need to opt-out from deprecation notices. Silencing swaps this behavior and allows users to opt-in when they are ready to cope with them (by adding a custom error handler like the one used by the Web Debug Toolbar or by the PHPUnit bridge).
When deprecating a whole class the
trigger_error() call should be placed
between the namespace and the use declarations, like in this example from
1 2 3 4 5 6 7 8 9 10
namespace Symfony\Component\Routing\Loader\DependencyInjection; use Symfony\Component\Routing\Loader\ContainerLoader; @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ServiceRouterLoader::class, ContainerLoader::class), E_USER_DEPRECATED); /** * @deprecated since Symfony 4.4, use Symfony\Component\Routing\Loader\ContainerLoader instead. */ class ServiceRouterLoader extends ObjectRouteLoader
The deprecation must be added to the
CHANGELOG.md file of the impacted component:
4.4.0 ----- * Deprecated the `Deprecated` class, use `Replacement` instead.
It must also be added to the
UPGRADE.md file of the targeted minor version
UPGRADE-4.4.md in our example):
DependencyInjection ------------------- * Deprecated the `Deprecated` class, use `Replacement` instead.
Finally, its consequences must be added to the
UPGRADE.md file of the next major version
UPGRADE-5.0.md in our example):
DependencyInjection ------------------- * Removed the `Deprecated` class, use `Replacement` instead.
All these tasks are mandatory and must be done in the same pull request.
Removing Deprecated Code¶
Removing deprecated code can only be done once every 2 years, on the next major version of the
impacted component (
When removing deprecated code, the consequences of the deprecation must be added to the
of the impacted component:
5.0.0 ----- * Removed the `Deprecated` class, use `Replacement` instead.
This task is mandatory and must be done in the same pull request.
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.