As of Symfony 2.3, we promise you backwards compatibility for all further 2.x releases. Ensuring smooth upgrades of your projects is our first priority. However, backwards compatibility comes in many different flavors.
This page has two different target audiences: If you are using Symfony, it will tell you how to make sure that you will be able to upgrade smoothly to all future 2.x versions. If you are contributing to Symfony, this page will tell you the rules that you need to follow to ensure smooth upgrades for our users.
Note
This promise is in trial until April 15th, 2014. Until then, we may change parts of it if we discover problems or limitations.
You are using Symfony in your projects? Then stick to the guidelines in this section in order to guarantee smooth upgrades to all future 2.x versions.
All interfaces in the Symfony
namespace are safe for use. That means
that:
- You can safely type hint against the interface.
- You can safely call any of the methods provided by the interface.
However:
- You cannot safely implement the interface. The interface may change, but all changes will be documented in the UPGRADE file.
Methods tagged with @api
are treated as if they belonged to an API
interface.
All interfaces tagged with @api
are also safe for implementation. That
means that:
- You can safely implement the interface.
Interfaces or interface methods tagged with @internal
are meant for internal
use in Symfony only. You should never use nor implement them.
Interfaces or interface methods tagged with @deprecated
will be removed in
a future Symfony version. You should never use nor implement them.
The following table summarizes the safe operations when using our interfaces:
Operation | Normal | API |
---|---|---|
Type hint against | Safe | Safe |
Call method | Safe | Safe |
In Implementing Classes | ||
Implement method | Not Safe [1] | Safe |
Add custom method | Not Safe [1] | Safe |
Add custom method parameter | Not Safe [1] | Safe |
Add parameter default value | Safe | Safe |
If you need to do any of the things marked as "Not Safe" above, feel free to
ask us whether the @api
tag can be added on the respective Symfony code.
For that, simply open a new ticket on GitHub.
All classes in the Symfony
namespace are safe for use. That means that:
- You can safely type hint against the class' name.
- You can safely create new instances.
- You can safely extend the class.
- You can safely access public properties.
- You can safely call public methods.
When extending the class:
- You can safely override public properties.
However:
- You cannot safely override methods in extending classes. The class may change, but all changes will be documented in the UPGRADE file.
Properties and methods tagged with @api
are treated as if they belonged
to an API class.
All classes tagged with @api
are also safe for extension. That means
that:
- You can safely access protected properties and methods.
- You can safely call protected methods.
- You can safely override protected properties.
- You can safely override public and protected methods.
Classes, properties and class methods tagged with @internal
are meant for
internal use in Symfony only. You should never use nor extend them.
Classes, properties and class methods tagged with @deprecated
will be
removed in a future Symfony version. You should never use nor extend them.
All classes located in the various *\\Tests\\
namespaces are meant for
internal use only. You should never create, extend or call them directly.
The following table summarizes the safe operations when using our classes:
Operation | Normal | API |
---|---|---|
Type hint against | Safe | Safe |
Create instance | Safe | Safe |
Extend | Safe | Safe |
Access public property | Safe | Safe |
Call public method | Safe | Safe |
In Extending Classes | ||
Access protected property | Not Safe [1] | Safe |
Call protected method | Not Safe [1] | Safe |
Override public property | Safe | Safe |
Override protected property | Not Safe [1] | Safe |
Override public method | Not Safe [1] | Safe |
Override protected method | Not Safe [1] | Safe |
Add custom property | Not Safe | Not Safe |
Add custom method | Not Safe | Not Safe |
Add custom method parameter | Not Safe [1] | Safe |
Add parameter default value | Safe | Safe |
If you need to do any of the things marked as "Not Safe" above, feel free to
ask us whether the @api
tag can be added on the respective Symfony code.
For that, simply open a new ticket on GitHub.
Do you want to help us improve Symfony? That's great! However, please stick to the rules listed below in order to ensure smooth upgrades for our users.
This table tells you which changes you are allowed to do when working on Symfony's interfaces:
Type of Change | Normal | API |
---|---|---|
Remove entirely | No | No |
Change name or namespace | No | No |
Add parent interface | Yes [2] | No |
Remove parent interface | No | No |
Methods | ||
Add method | Yes [2] | No |
Remove method | No | No |
Change name | No | No |
Add parameter without a default value | No | No |
Add parameter with a default value | Yes [2] | No |
Remove parameter | Yes [3] | Yes [3] |
Add default value to a parameter | Yes [2] | No |
Remove default value of a parameter | No | No |
Add type hint to a parameter | No | No |
Remove type hint of a parameter | Yes [2] | No |
Change parameter type | Yes [2] [4] | No |
Change return type | Yes [2] [5] | No |
This table tells you which changes you are allowed to do when working on Symfony's classes:
Type of Change | Normal | API |
---|---|---|
Remove entirely | No | No |
Make final | Yes [2] | No |
Make abstract | No | No |
Change name or namespace | No | No |
Change parent class | Yes [6] | Yes [6] |
Add interface | Yes | Yes |
Remove interface | No | No |
Public Properties | ||
Add public property | Yes | Yes |
Remove public property | No | No |
Reduce visibility | No | No |
Protected Properties | ||
Add protected property | Yes | Yes |
Remove protected property | Yes [2] | No |
Reduce visibility | Yes [2] | No |
Constructors | ||
Add constructor without mandatory parameters | Yes [2] | Yes [2] |
Remove constructor | Yes [2] | No |
Reduce visibility of a public constructor | No | No |
Reduce visibility of a protected constructor | Yes [2] | No |
Public Methods | ||
Add public method | Yes | Yes |
Remove public method | No | No |
Change name | No | No |
Reduce visibility | No | No |
Add parameter without a default value | No | No |
Add parameter with a default value | Yes [2] | No |
Remove parameter | Yes [3] | Yes [3] |
Add default value to a parameter | Yes [2] | No |
Remove default value of a parameter | No | No |
Add type hint to a parameter | Yes [7] | No |
Remove type hint of a parameter | Yes [2] | No |
Change parameter type | Yes [2] [4] | No |
Change return type | Yes [2] [5] | No |
Protected Methods | ||
Add protected method | Yes | Yes |
Remove protected method | Yes [2] | No |
Change name | No | No |
Reduce visibility | Yes [2] | No |
Add parameter without a default value | Yes [2] | No |
Add parameter with a default value | Yes [2] | No |
Remove parameter | Yes [3] | Yes [3] |
Add default value to a parameter | Yes [2] | No |
Remove default value of a parameter | Yes [2] | No |
Add type hint to a parameter | Yes [2] | No |
Remove type hint of a parameter | Yes [2] | No |
Change parameter type | Yes [2] [4] | No |
Change return type | Yes [2] [5] | No |
[1] | (1, 2, 3, 4, 5, 6, 7, 8, 9) Your code may be broken by changes in the Symfony code. Such changes will however be documented in the UPGRADE file. |
[2] | (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29) Should be avoided. When done, this change must be documented in the UPGRADE file. |
[3] | (1, 2, 3, 4, 5, 6) Only the last parameter(s) of a method may be removed. |
[4] | (1, 2, 3) The parameter type may only be changed to a compatible or less specific type. The following type changes are allowed:
|
[5] | (1, 2, 3) The return type may only be changed to a compatible or more specific type. The following type changes are allowed:
|
[6] | (1, 2) When changing the parent class, the original parent class must remain an ancestor of the class. |
[7] | A type hint may only be added if passing a value with a different type previously generated a fatal error. |