diff --git a/contributing/code/bc.rst b/contributing/code/bc.rst index 95613bd1763..905accabb6e 100644 --- a/contributing/code/bc.rst +++ b/contributing/code/bc.rst @@ -51,53 +51,28 @@ sticks to these rules. The exception to this rule are interfaces tagged with ``@internal``. Such interfaces should not be used or implemented. -If you want to implement an interface, you should first make sure that the -interface is an API interface. You can recognize API interfaces by the ``@api`` -tag in their source code:: - - /** - * HttpKernelInterface handles a Request to convert it to a Response. - * - * @author Fabien Potencier - * - * @api - */ - interface HttpKernelInterface - { - // ... - } - -If you implement an API interface, we promise that we won't ever break your -code. Regular interfaces, by contrast, may be extended between minor releases, -for example by adding a new method. Be prepared to upgrade your code manually -if you implement a regular interface. - -.. note:: - - Even if we do changes that require manual upgrades, we limit ourselves to - changes that can be upgraded easily. We will always document the precise - upgrade instructions in the UPGRADE file in Symfony's root directory. +If you implement an interface, we promise that we won't ever break your code. The following table explains in detail which use cases are covered by our backwards compatibility promise: -+-----------------------------------------------+---------------+---------------+ -| Use Case | Regular | API | -+===============================================+===============+===============+ -| **If you...** | **Then we guarantee BC...** | -+-----------------------------------------------+---------------+---------------+ -| Type hint against the interface | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| Call a method | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| **If you implement the interface and...** | **Then we guarantee BC...** | -+-----------------------------------------------+---------------+---------------+ -| Implement a method | No [1]_ | Yes | -+-----------------------------------------------+---------------+---------------+ -| Add an argument to an implemented method | No [1]_ | Yes | -+-----------------------------------------------+---------------+---------------+ -| Add a default value to an argument | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ ++-----------------------------------------------+-----------------------------+ +| Use Case | Backwards Compatibility | ++===============================================+=============================+ +| **If you...** | **Then we guarantee BC...** | ++-----------------------------------------------+-----------------------------+ +| Type hint against the interface | Yes | ++-----------------------------------------------+-----------------------------+ +| Call a method | Yes | ++-----------------------------------------------+-----------------------------+ +| **If you implement the interface and...** | **Then we guarantee BC...** | ++-----------------------------------------------+-----------------------------+ +| Implement a method | Yes | ++-----------------------------------------------+-----------------------------+ +| Add an argument to an implemented method | Yes | ++-----------------------------------------------+-----------------------------+ +| Add a default value to an argument | Yes | ++-----------------------------------------------+-----------------------------+ .. include:: _api_tagging.rst.inc @@ -114,82 +89,50 @@ public methods and properties. exception to this rule. They are meant for internal use only and should not be accessed by your own code. -Just like with interfaces, we also distinguish between regular and API classes. -Like API interfaces, API classes are marked with an ``@api`` tag:: - - /** - * Request represents an HTTP request. - * - * @author Fabien Potencier - * - * @api - */ - class Request - { - // ... - } - -The difference between regular and API classes is that we guarantee full -backwards compatibility if you extend an API class and override its methods. We -can't give the same promise for regular classes, because there we may, for -example, add an optional argument to a method. Consequently, the signature of -your overridden method wouldn't match anymore and generate a fatal error. - -.. note:: - - As with interfaces, we limit ourselves to changes that can be upgraded - easily. We will document the precise upgrade instructions in the UPGRADE - file in Symfony's root directory. - -In some cases, only specific properties and methods are tagged with the ``@api`` -tag, even though their class is not. In these cases, we guarantee full backwards -compatibility for the tagged properties and methods (as indicated in the column -"API" below), but not for the rest of the class. - To be on the safe side, check the following table to know which use cases are covered by our backwards compatibility promise: -+-----------------------------------------------+---------------+---------------+ -| Use Case | Regular | API | -+===============================================+===============+===============+ -| **If you...** | **Then we guarantee BC...** | -+-----------------------------------------------+---------------+---------------+ -| Type hint against the class | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| Create a new instance | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| Extend the class | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| Access a public property | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| Call a public method | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| **If you extend the class and...** | **Then we guarantee BC...** | -+-----------------------------------------------+---------------+---------------+ -| Access a protected property | No [1]_ | Yes | -+-----------------------------------------------+---------------+---------------+ -| Call a protected method | No [1]_ | Yes | -+-----------------------------------------------+---------------+---------------+ -| Override a public property | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| Override a protected property | No [1]_ | Yes | -+-----------------------------------------------+---------------+---------------+ -| Override a public method | No [1]_ | Yes | -+-----------------------------------------------+---------------+---------------+ -| Override a protected method | No [1]_ | Yes | -+-----------------------------------------------+---------------+---------------+ -| Add a new property | No | No | -+-----------------------------------------------+---------------+---------------+ -| Add a new method | No | No | -+-----------------------------------------------+---------------+---------------+ -| Add an argument to an overridden method | No [1]_ | Yes | -+-----------------------------------------------+---------------+---------------+ -| Add a default value to an argument | Yes | Yes | -+-----------------------------------------------+---------------+---------------+ -| Call a private method (via Reflection) | No | No | -+-----------------------------------------------+---------------+---------------+ -| Access a private property (via Reflection) | No | No | -+-----------------------------------------------+---------------+---------------+ ++-----------------------------------------------+-----------------------------+ +| Use Case | Backwards Compatibility | ++===============================================+=============================+ +| **If you...** | **Then we guarantee BC...** | ++-----------------------------------------------+-----------------------------+ +| Type hint against the class | Yes | ++-----------------------------------------------+-----------------------------+ +| Create a new instance | Yes | ++-----------------------------------------------+-----------------------------+ +| Extend the class | Yes | ++-----------------------------------------------+-----------------------------+ +| Access a public property | Yes | ++-----------------------------------------------+-----------------------------+ +| Call a public method | Yes | ++-----------------------------------------------+-----------------------------+ +| **If you extend the class and...** | **Then we guarantee BC...** | ++-----------------------------------------------+-----------------------------+ +| Access a protected property | Yes | ++-----------------------------------------------+-----------------------------+ +| Call a protected method | Yes | ++-----------------------------------------------+-----------------------------+ +| Override a public property | Yes | ++-----------------------------------------------+-----------------------------+ +| Override a protected property | Yes | ++-----------------------------------------------+-----------------------------+ +| Override a public method | Yes | ++-----------------------------------------------+-----------------------------+ +| Override a protected method | Yes | ++-----------------------------------------------+-----------------------------+ +| Add a new property | No | ++-----------------------------------------------+-----------------------------+ +| Add a new method | No | ++-----------------------------------------------+-----------------------------+ +| Add an argument to an overridden method | Yes | ++-----------------------------------------------+-----------------------------+ +| Add a default value to an argument | Yes | ++-----------------------------------------------+-----------------------------+ +| Call a private method (via Reflection) | No | ++-----------------------------------------------+-----------------------------+ +| Access a private property (via Reflection) | No | ++-----------------------------------------------+-----------------------------+ .. include:: _api_tagging.rst.inc @@ -205,28 +148,28 @@ Changing Interfaces This table tells you which changes you are allowed to do when working on Symfony's interfaces: -============================================== ============== ============== -Type of Change Regular API -============================================== ============== ============== -Remove entirely No No -Change name or namespace No No -Add parent interface Yes [2]_ Yes [3]_ -Remove parent interface No No +============================================== ============== +Type of Change Change Allowed +============================================== ============== +Remove entirely No +Change name or namespace No +Add parent interface Yes [2]_ +Remove parent interface No **Methods** -Add method Yes [2]_ No -Remove method No No -Change name No No -Move to parent interface Yes Yes -Add argument without a default value No No -Add argument with a default value Yes [2]_ No -Remove argument Yes [4]_ Yes [4]_ -Add default value to an argument Yes [2]_ No -Remove default value of an argument No No -Add type hint to an argument No No -Remove type hint of an argument Yes [2]_ No -Change argument type Yes [2]_ [5]_ No -Change return type Yes [2]_ [6]_ No -============================================== ============== ============== +Add method No +Remove method No +Change name No +Move to parent interface Yes +Add argument without a default value No +Add argument with a default value No +Remove argument Yes [3]_ +Add default value to an argument No +Remove default value of an argument No +Add type hint to an argument No +Remove type hint of an argument No +Change argument type No +Change return type No +============================================== ============== Changing Classes ~~~~~~~~~~~~~~~~ @@ -234,134 +177,96 @@ Changing Classes This table tells you which changes you are allowed to do when working on Symfony's classes: -================================================== ============== ============== -Type of Change Regular API -================================================== ============== ============== -Remove entirely No No -Make final No No -Make abstract No No -Change name or namespace No No -Change parent class Yes [7]_ Yes [7]_ -Add interface Yes Yes -Remove interface No No +================================================== ============== +Type of Change Change Allowed +================================================== ============== +Remove entirely No +Make final No +Make abstract No +Change name or namespace No +Change parent class Yes [4]_ +Add interface Yes +Remove interface No **Public Properties** -Add public property Yes Yes -Remove public property No No -Reduce visibility No No -Move to parent class Yes Yes +Add public property Yes +Remove public property No +Reduce visibility No +Move to parent class Yes **Protected Properties** -Add protected property Yes Yes -Remove protected property Yes [2]_ No -Reduce visibility Yes [2]_ No -Move to parent class Yes Yes +Add protected property Yes +Remove protected property No +Reduce visibility No +Move to parent class Yes **Private Properties** -Add private property Yes Yes -Remove private property Yes Yes +Add private property Yes +Remove private property Yes **Constructors** -Add constructor without mandatory arguments 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 -Move to parent class Yes Yes +Add constructor without mandatory arguments Yes [1]_ +Remove constructor No +Reduce visibility of a public constructor No +Reduce visibility of a protected constructor No +Move to parent class Yes **Public Methods** -Add public method Yes Yes -Remove public method No No -Change name No No -Reduce visibility No No -Move to parent class Yes Yes -Add argument without a default value No No -Add argument with a default value Yes [2]_ No -Remove argument Yes [4]_ Yes [4]_ -Add default value to an argument Yes [2]_ No -Remove default value of an argument No No -Add type hint to an argument Yes [8]_ No -Remove type hint of an argument Yes [2]_ No -Change argument type Yes [2]_ [5]_ No -Change return type Yes [2]_ [6]_ No +Add public method Yes +Remove public method No +Change name No +Reduce visibility No +Move to parent class Yes +Add argument without a default value No +Add argument with a default value No +Remove argument Yes [3]_ +Add default value to an argument No +Remove default value of an argument No +Add type hint to an argument No +Remove type hint of an argument No +Change argument type No +Change return type No **Protected Methods** -Add protected method Yes Yes -Remove protected method Yes [2]_ No -Change name No No -Reduce visibility Yes [2]_ No -Move to parent class Yes Yes -Add argument without a default value Yes [2]_ No -Add argument with a default value Yes [2]_ No -Remove argument Yes [4]_ Yes [4]_ -Add default value to an argument Yes [2]_ No -Remove default value of an argument Yes [2]_ No -Add type hint to an argument Yes [2]_ No -Remove type hint of an argument Yes [2]_ No -Change argument type Yes [2]_ [5]_ No -Change return type Yes [2]_ [6]_ No +Add protected method Yes +Remove protected method No +Change name No +Reduce visibility No +Move to parent class Yes +Add argument without a default value No +Add argument with a default value No +Remove argument Yes [3]_ +Add default value to an argument No +Remove default value of an argument No +Add type hint to an argument No +Remove type hint of an argument No +Change argument type No +Change return type No **Private Methods** -Add private method Yes Yes -Remove private method Yes Yes -Change name Yes Yes -Reduce visibility Yes Yes -Add argument without a default value Yes Yes -Add argument with a default value Yes Yes -Remove argument Yes Yes -Add default value to an argument Yes Yes -Remove default value of an argument Yes Yes -Add type hint to an argument Yes Yes -Remove type hint of an argument Yes Yes -Change argument type Yes Yes -Change return type Yes Yes +Add private method Yes +Remove private method Yes +Change name Yes +Reduce visibility Yes +Add argument without a default value Yes +Add argument with a default value Yes +Remove argument Yes +Add default value to an argument Yes +Remove default value of an argument Yes +Add type hint to an argument Yes +Remove type hint of an argument Yes +Change argument type Yes +Change return type Yes **Static Methods** -Turn non static into static No No -Turn static into non static No No -================================================== ============== ============== - -.. [1] Your code may be broken by changes in the Symfony code. Such changes will - however be documented in the UPGRADE file. +Turn non static into static No +Turn static into non static No +================================================== ============== -.. [2] Should be avoided. When done, this change must be documented in the +.. [1] Should be avoided. When done, this change must be documented in the UPGRADE file. -.. [3] The added parent interface must not introduce any new methods that don't +.. [2] The added parent interface must not introduce any new methods that don't exist in the interface already. -.. [4] Only the last argument(s) of a method may be removed, as PHP does not +.. [3] Only the last argument(s) of a method may be removed, as PHP does not care about additional arguments that you pass to a method. -.. [5] The argument type may only be changed to a compatible or less specific - type. The following type changes are allowed: - - =================== ================================================================== - Original Type New Type - =================== ================================================================== - boolean any `scalar type`_ with equivalent `boolean values`_ - string any `scalar type`_ or object with equivalent `string values`_ - integer any `scalar type`_ with equivalent `integer values`_ - float any `scalar type`_ with equivalent `float values`_ - class ```` any superclass or interface of ```` - interface ```` any superinterface of ```` - =================== ================================================================== - -.. [6] The return type may only be changed to a compatible or more specific - type. The following type changes are allowed: - - =================== ================================================================== - Original Type New Type - =================== ================================================================== - boolean any `scalar type`_ with equivalent `boolean values`_ - string any `scalar type`_ or object with equivalent `string values`_ - integer any `scalar type`_ with equivalent `integer values`_ - float any `scalar type`_ with equivalent `float values`_ - array instance of ``ArrayAccess``, ``Traversable`` and ``Countable`` - ``ArrayAccess`` array - ``Traversable`` array - ``Countable`` array - class ```` any subclass of ```` - interface ```` any subinterface or implementing class of ```` - =================== ================================================================== - -.. [7] When changing the parent class, the original parent class must remain an +.. [4] When changing the parent class, the original parent class must remain an ancestor of the class. -.. [8] A type hint may only be added if passing a value with a different type - previously generated a fatal error. - .. _Semantic Versioning: http://semver.org/ .. _scalar type: http://php.net/manual/en/function.is-scalar.php .. _boolean values: http://php.net/manual/en/function.boolval.php pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy