Skip to content

Commit cadca3b

Browse files
committedFeb 20, 2014
Merge branch '2.4'
2 parents 2cb2c2d + 77628d0 commit cadca3b

File tree

4 files changed

+379
-3
lines changed

4 files changed

+379
-3
lines changed
 
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. note::
2+
3+
If you think that one of our regular classes should have an ``@api`` tag,
4+
put your request into a `new ticket on GitHub`_. We will then evaluate
5+
whether we can add the tag or not.
6+
7+
.. _new ticket on GitHub: https://github.com/symfony/symfony/issues/new

‎contributing/code/bc.rst‎

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
Our Backwards Compatibility Promise
2+
===================================
3+
4+
Ensuring smooth upgrades of your projects is our first priority. That's why
5+
we promise you backwards compatibility (BC) for all minor Symfony releases.
6+
You probably recognize this strategy as `Semantic Versioning`_. In short,
7+
Semantic Versioning means that only major releases (such as 2.0, 3.0 etc.) are
8+
allowed to break backwards compatibility. Minor releases (such as 2.5, 2.6 etc.)
9+
may introduce new features, but must do so without breaking the existing API of
10+
that release branch (2.x in the previous example).
11+
12+
.. caution::
13+
14+
This promise was introduced with Symfony 2.3 and does not apply to previous
15+
versions of Symfony.
16+
17+
However, backwards compatibility comes in many different flavors. In fact, almost
18+
every change that we make to the framework can potentially break an application.
19+
For example, if we add a new method to a class, this will break an application
20+
which extended this class and added the same method, but with a different
21+
method signature.
22+
23+
Also, not every BC break has the same impact on application code. While some BC
24+
breaks require you to make significant changes to your classes or your
25+
architecture, others are fixed as easily as changing the name of a method.
26+
27+
That's why we created this page for you. The section "Using Symfony Code" will
28+
tell you how you can ensure that your application won't break completely when
29+
upgrading to a newer version of the same major release branch.
30+
31+
The second section, "Working on Symfony Code", is targeted at Symfony
32+
contributors. This section lists detailed rules that every contributor needs to
33+
follow to ensure smooth upgrades for our users.
34+
35+
Using Symfony Code
36+
------------------
37+
38+
If you are using Symfony in your projects, the following guidelines will help
39+
you to ensure smooth upgrades to all future minor releases of your Symfony
40+
version.
41+
42+
Using Our Interfaces
43+
~~~~~~~~~~~~~~~~~~~~
44+
45+
All interfaces shipped with Symfony can be used in type hints. You can also call
46+
any of the methods that they declare. We guarantee that we won't break code that
47+
sticks to these rules.
48+
49+
.. caution::
50+
51+
The exception to this rule are interfaces tagged with ``@internal``. Such
52+
interfaces should not be used or implemented.
53+
54+
If you want to implement an interface, you should first make sure that the
55+
interface is an API interface. You can recognize API interfaces by the ``@api``
56+
tag in their source code::
57+
58+
/**
59+
* HttpKernelInterface handles a Request to convert it to a Response.
60+
*
61+
* @author Fabien Potencier <fabien@symfony.com>
62+
*
63+
* @api
64+
*/
65+
interface HttpKernelInterface
66+
{
67+
// ...
68+
}
69+
70+
If you implement an API interface, we promise that we won't ever break your
71+
code. Regular interfaces, by contrast, may be extended between minor releases,
72+
for example by adding a new method. Be prepared to upgrade your code manually
73+
if you implement a regular interface.
74+
75+
.. note::
76+
77+
Even if we do changes that require manual upgrades, we limit ourselves to
78+
changes that can be upgraded easily. We will always document the precise
79+
upgrade instructions in the UPGRADE file in Symfony's root directory.
80+
81+
The following table explains in detail which use cases are covered by our
82+
backwards compatibility promise:
83+
84+
+-----------------------------------------------+---------------+---------------+
85+
| Use Case | Regular | API |
86+
+===============================================+===============+===============+
87+
| **If you...** | **Then we guarantee BC...** |
88+
+-----------------------------------------------+---------------+---------------+
89+
| Type hint against the interface | Yes | Yes |
90+
+-----------------------------------------------+---------------+---------------+
91+
| Call a method | Yes | Yes |
92+
+-----------------------------------------------+---------------+---------------+
93+
| **If you implement the interface and...** | **Then we guarantee BC...** |
94+
+-----------------------------------------------+---------------+---------------+
95+
| Implement a method | No [1]_ | Yes |
96+
+-----------------------------------------------+---------------+---------------+
97+
| Add an argument to an implemented method | No [1]_ | Yes |
98+
+-----------------------------------------------+---------------+---------------+
99+
| Add a default value to an argument | Yes | Yes |
100+
+-----------------------------------------------+---------------+---------------+
101+
102+
.. include:: _api_tagging.rst.inc
103+
104+
Using Our Classes
105+
~~~~~~~~~~~~~~~~~
106+
107+
All classes provided by Symfony may be instantiated and accessed through their
108+
public methods and properties.
109+
110+
.. caution::
111+
112+
Classes, properties and methods that bear the tag ``@internal`` as well as
113+
the classes located in the various ``*\\Tests\\`` namespaces are an
114+
exception to this rule. They are meant for internal use only and should
115+
not be accessed by your own code.
116+
117+
Just like with interfaces, we also distinguish between regular and API classes.
118+
Like API interfaces, API classes are marked with an ``@api`` tag::
119+
120+
/**
121+
* Request represents an HTTP request.
122+
*
123+
* @author Fabien Potencier <fabien@symfony.com>
124+
*
125+
* @api
126+
*/
127+
class Request
128+
{
129+
// ...
130+
}
131+
132+
The difference between regular and API classes is that we guarantee full
133+
backwards compatibility if you extend an API class and override its methods. We
134+
can't give the same promise for regular classes, because there we may, for
135+
example, add an optional argument to a method. Consequently, the signature of
136+
your overridden method wouldn't match anymore and generate a fatal error.
137+
138+
.. note::
139+
140+
As with interfaces, we limit ourselves to changes that can be upgraded
141+
easily. We will document the precise ugprade instructions in the UPGRADE
142+
file in Symfony's root directory.
143+
144+
In some cases, only specific properties and methods are tagged with the ``@api``
145+
tag, even though their class is not. In these cases, we guarantee full backwards
146+
compatibility for the tagged properties and methods (as indicated in the column
147+
"API" below), but not for the rest of the class.
148+
149+
To be on the safe side, check the following table to know which use cases are
150+
covered by our backwards compatibility promise:
151+
152+
+-----------------------------------------------+---------------+---------------+
153+
| Use Case | Regular | API |
154+
+===============================================+===============+===============+
155+
| **If you...** | **Then we guarantee BC...** |
156+
+-----------------------------------------------+---------------+---------------+
157+
| Type hint against the class | Yes | Yes |
158+
+-----------------------------------------------+---------------+---------------+
159+
| Create a new instance | Yes | Yes |
160+
+-----------------------------------------------+---------------+---------------+
161+
| Extend the class | Yes | Yes |
162+
+-----------------------------------------------+---------------+---------------+
163+
| Access a public property | Yes | Yes |
164+
+-----------------------------------------------+---------------+---------------+
165+
| Call a public method | Yes | Yes |
166+
+-----------------------------------------------+---------------+---------------+
167+
| **If you extend the class and...** | **Then we guarantee BC...** |
168+
+-----------------------------------------------+---------------+---------------+
169+
| Access a protected property | No [1]_ | Yes |
170+
+-----------------------------------------------+---------------+---------------+
171+
| Call a protected method | No [1]_ | Yes |
172+
+-----------------------------------------------+---------------+---------------+
173+
| Override a public property | Yes | Yes |
174+
+-----------------------------------------------+---------------+---------------+
175+
| Override a protected property | No [1]_ | Yes |
176+
+-----------------------------------------------+---------------+---------------+
177+
| Override a public method | No [1]_ | Yes |
178+
+-----------------------------------------------+---------------+---------------+
179+
| Override a protected method | No [1]_ | Yes |
180+
+-----------------------------------------------+---------------+---------------+
181+
| Add a new property | No | No |
182+
+-----------------------------------------------+---------------+---------------+
183+
| Add a new method | No | No |
184+
+-----------------------------------------------+---------------+---------------+
185+
| Add an argument to an overridden method | No [1]_ | Yes |
186+
+-----------------------------------------------+---------------+---------------+
187+
| Add a default value to an argument | Yes | Yes |
188+
+-----------------------------------------------+---------------+---------------+
189+
| Call a private method (via Reflection) | No | No |
190+
+-----------------------------------------------+---------------+---------------+
191+
| Access a private property (via Reflection) | No | No |
192+
+-----------------------------------------------+---------------+---------------+
193+
194+
.. include:: _api_tagging.rst.inc
195+
196+
Working on Symfony Code
197+
-----------------------
198+
199+
Do you want to help us improve Symfony? That's great! However, please stick
200+
to the rules listed below in order to ensure smooth upgrades for our users.
201+
202+
Changing Interfaces
203+
~~~~~~~~~~~~~~~~~~~
204+
205+
This table tells you which changes you are allowed to do when working on
206+
Symfony's interfaces:
207+
208+
============================================== ============== ==============
209+
Type of Change Regular API
210+
============================================== ============== ==============
211+
Remove entirely No No
212+
Change name or namespace No No
213+
Add parent interface Yes [2]_ Yes [3]_
214+
Remove parent interface No No
215+
**Methods**
216+
Add method Yes [2]_ No
217+
Remove method No No
218+
Change name No No
219+
Move to parent interface Yes Yes
220+
Add argument without a default value No No
221+
Add argument with a default value Yes [2]_ No
222+
Remove argument Yes [4]_ Yes [4]_
223+
Add default value to an argument Yes [2]_ No
224+
Remove default value of an argument No No
225+
Add type hint to an argument No No
226+
Remove type hint of an argument Yes [2]_ No
227+
Change argument type Yes [2]_ [5]_ No
228+
Change return type Yes [2]_ [6]_ No
229+
============================================== ============== ==============
230+
231+
Changing Classes
232+
~~~~~~~~~~~~~~~~
233+
234+
This table tells you which changes you are allowed to do when working on
235+
Symfony's classes:
236+
237+
================================================== ============== ==============
238+
Type of Change Regular API
239+
================================================== ============== ==============
240+
Remove entirely No No
241+
Make final Yes [2]_ No
242+
Make abstract No No
243+
Change name or namespace No No
244+
Change parent class Yes [7]_ Yes [7]_
245+
Add interface Yes Yes
246+
Remove interface No No
247+
**Public Properties**
248+
Add public property Yes Yes
249+
Remove public property No No
250+
Reduce visibility No No
251+
Move to parent class Yes Yes
252+
**Protected Properties**
253+
Add protected property Yes Yes
254+
Remove protected property Yes [2]_ No
255+
Reduce visibility Yes [2]_ No
256+
Move to parent class Yes Yes
257+
**Private Properties**
258+
Add private property Yes Yes
259+
Remove private property Yes Yes
260+
**Constructors**
261+
Add constructor without mandatory arguments Yes [2]_ Yes [2]_
262+
Remove constructor Yes [2]_ No
263+
Reduce visibility of a public constructor No No
264+
Reduce visibility of a protected constructor Yes [2]_ No
265+
Move to parent class Yes Yes
266+
**Public Methods**
267+
Add public method Yes Yes
268+
Remove public method No No
269+
Change name No No
270+
Reduce visibility No No
271+
Move to parent class Yes Yes
272+
Add argument without a default value No No
273+
Add argument with a default value Yes [2]_ No
274+
Remove argument Yes [4]_ Yes [4]_
275+
Add default value to an argument Yes [2]_ No
276+
Remove default value of an argument No No
277+
Add type hint to an argument Yes [8]_ No
278+
Remove type hint of an argument Yes [2]_ No
279+
Change argument type Yes [2]_ [5]_ No
280+
Change return type Yes [2]_ [6]_ No
281+
**Protected Methods**
282+
Add protected method Yes Yes
283+
Remove protected method Yes [2]_ No
284+
Change name No No
285+
Reduce visibility Yes [2]_ No
286+
Move to parent class Yes Yes
287+
Add argument without a default value Yes [2]_ No
288+
Add argument with a default value Yes [2]_ No
289+
Remove argument Yes [4]_ Yes [4]_
290+
Add default value to an argument Yes [2]_ No
291+
Remove default value of an argument Yes [2]_ No
292+
Add type hint to an argument Yes [2]_ No
293+
Remove type hint of an argument Yes [2]_ No
294+
Change argument type Yes [2]_ [5]_ No
295+
Change return type Yes [2]_ [6]_ No
296+
**Private Methods**
297+
Add private method Yes Yes
298+
Remove private method Yes Yes
299+
Change name Yes Yes
300+
Reduce visibility Yes Yes
301+
Add argument without a default value Yes Yes
302+
Add argument with a default value Yes Yes
303+
Remove argument Yes Yes
304+
Add default value to an argument Yes Yes
305+
Remove default value of an argument Yes Yes
306+
Add type hint to an argument Yes Yes
307+
Remove type hint of an argument Yes Yes
308+
Change argument type Yes Yes
309+
Change return type Yes Yes
310+
================================================== ============== ==============
311+
312+
.. [1] Your code may be broken by changes in the Symfony code. Such changes will
313+
however be documented in the UPGRADE file.
314+
315+
.. [2] Should be avoided. When done, this change must be documented in the
316+
UPGRADE file.
317+
318+
.. [3] The added parent interface must not introduce any new methods that don't
319+
exist in the interface already.
320+
321+
.. [4] Only the last argument(s) of a method may be removed, as PHP does not
322+
care about additional arguments that you pass to a method.
323+
324+
.. [5] The argument type may only be changed to a compatible or less specific
325+
type. The following type changes are allowed:
326+
327+
=================== ==================================================================
328+
Original Type New Type
329+
=================== ==================================================================
330+
boolean any `scalar type`_ with equivalent `boolean values`_
331+
string any `scalar type`_ or object with equivalent `string values`_
332+
integer any `scalar type`_ with equivalent `integer values`_
333+
float any `scalar type`_ with equivalent `float values`_
334+
class ``<C>`` any superclass or interface of ``<C>``
335+
interface ``<I>`` any superinterface of ``<I>``
336+
=================== ==================================================================
337+
338+
.. [6] The return type may only be changed to a compatible or more specific
339+
type. The following type changes are allowed:
340+
341+
=================== ==================================================================
342+
Original Type New Type
343+
=================== ==================================================================
344+
boolean any `scalar type`_ with equivalent `boolean values`_
345+
string any `scalar type`_ or object with equivalent `string values`_
346+
integer any `scalar type`_ with equivalent `integer values`_
347+
float any `scalar type`_ with equivalent `float values`_
348+
array instance of ``ArrayAccess``, ``Traversable`` and ``Countable``
349+
``ArrayAccess`` array
350+
``Traversable`` array
351+
``Countable`` array
352+
class ``<C>`` any subclass of ``<C>``
353+
interface ``<I>`` any subinterface or implementing class of ``<I>``
354+
=================== ==================================================================
355+
356+
.. [7] When changing the parent class, the original parent class must remain an
357+
ancestor of the class.
358+
359+
.. [8] A type hint may only be added if passing a value with a different type
360+
previously generated a fatal error.
361+
362+
.. _Semantic Versioning: http://semver.org/
363+
.. _scalar type: http://php.net/manual/en/function.is-scalar.php
364+
.. _boolean values: http://php.net/manual/en/function.boolval.php
365+
.. _string values: http://www.php.net/manual/en/function.strval.php
366+
.. _integer values: http://www.php.net/manual/en/function.intval.php
367+
.. _float values: http://www.php.net/manual/en/function.floatval.php

‎contributing/code/index.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Contributing Code
88
patches
99
security
1010
tests
11+
bc
1112
standards
1213
conventions
1314
git

‎contributing/map.rst.inc‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
* :doc:`Patches </contributing/code/patches>`
55
* :doc:`Security </contributing/code/security>`
66
* :doc:`Tests </contributing/code/tests>`
7-
* :doc:`Coding Standards </contributing/code/standards>`
8-
* :doc:`Code Conventions </contributing/code/conventions>`
9-
* :doc:`Git </contributing/code/git>`
7+
* :doc:`Backwards Compatibility </contributing/code/bc>`
8+
* :doc:`Coding Standards</contributing/code/standards>`
9+
* :doc:`Code Conventions</contributing/code/conventions>`
10+
* :doc:`Git</contributing/code/git>`
1011
* :doc:`License </contributing/code/license>`
1112

1213
* **Documentation**

0 commit comments

Comments
 (0)
Please sign in to comment.