Наше обещание обратной совместимости

Гарантирование плавного обновления ваших проектов является нашим главным приоритетом. Поэтому мы обещаем вам обратную совместимость (ОС) для всех небольших релизов Symfony. Вы скорее всего знаете эту стратегию, как Семантическое версионирование. Кратко говоря, Семантическое версионирование означает, что только крупные релизы (вроде 2.0, 3.0 и т.д.) могут нарушать обратную совместимость. Небольшие релизы (вроде 2.5, 2.6 и т.д.) могут представлять новые функции, но должны делать это не нарушая существующий API этой ветки релиза (в предыдущем примере - 2.x).

Caution

Это обещание было представлено в Symfony 2.3 и не применяется к предыдущим версиям Symfony.

Однако, обратная совместимость имеет множество разных форм. На самом деле, почти каждое изменение, которое мы делаем в фреймворке, может потенциально сломать приложение. Например, если мы добавим новый метод в класс, это сломает приложение, которое расширяло этот класс и добавляло тот же метод, но с другой подписью метода.

Также, не каждая ОС имеет одинаковое влияние на код приложения. В то время, как некоторые поломки ОС требуют существенных изменений в ваших классах или архитектуре, другие исправляются простым изменением имени метода.

Поэтому мы создали эту страницу для вас. Раздел "Использование кода Symfony" расскажет вам о том, как вы можете гарантировать, что ваше приложение не сломается полностью при обновлении на более новую версию одной ветки большого релиза.

Второй раздел, "Работа над кодом Symfony", направлена на вкладчиков Symfony. Этот раздел печисляет подробные правила, которым дожен следовать каждый вкладчик, чтобы гарантировать плавные обновления для наших пользователей.

Warning

Экспериментальные функции и код, маркированный тегами @internal, исключаются из нашего обещания обратной совместимости.

Также отметьте, что нарушения обратной совместимости прощаются, если они необходимы для починки проблемы безопасности.

Использование кода Symfony

Если вы используете Symfony в ваших проектах, то следующие правила помогут вам гарантировать плавные обновления до всех небольших релизов вашей версии Symfony.

Использование наших интерфейсов

Все интерфейсы, поставляющиеся с Symfony могут быть использованы в типизации. Вы также можете вызвать любой из заявленных ими методов. Мы гарантируем,что это не сломает код, следующий этим правилам.

Caution

Исключением из этого правила являются интерфейсы, тегированные @internal. Такие интерфейсы не должны быть использованы или реализованы.

Если вы реализуете интерфейс, мы обещаем, что никогда не сломаем ваш код.

Следующая таблица в деталях объясняет, какие случаи использования охватываются нашим обещанием обратной совместимости:

Случай использования Обратная совместимость
Если вы... То мы гарантируем ОС...
Типизируете в интерфейсе Да
Вызываете метод Да
Если вы реализуете интерфейс и... То мы гарантируем ОС...
Реализуете метод Да
Добавляете аргумент в реализованный метод Да
Добавляете значение по умолчанию в аргумент Да

Использование наших классов

Все классы, предоставленные Symfony могут быть инстанциированы и доступны через их публичные методы и свойства.

Caution

Классы, свойства и методы, которые хранят тег @internal, а также классы, расположенные в различных пространствах имён *\\Tests\\ являются исключением из этого правила. Они предназначены только для внутреннего использования и не должны быть доступны из вашего собственного кода.

Чтобы перестраховаться, просмотрите следующую таблицу, чтобы знать, какие случаи использования охватываются нашим обещанием обратной совместимости:

Случай использования Обратная совместимость
Если вы... То мы гаранируем ОС...
Типизириуете в классе Да
Создаёте новый экземпляр Да
Расширяете класс Да
Получаете доступ к публичному свойству Да
Вызываете публичный метод Да
Если вы расширяете класс и... То мы гаранируем ОС...
Получаете доступ к защищённому свойству Да
Вызываете защищённый метод Да
Переопределяете публичное свойство Да
Переопределяете защищённое свойство Да
Переопределяете публичный метод Да
Переопределяете защищённый метод Да
Добавляете новое свойство Нет
Добавляете новый метод Нет
Добавляете аргумен к переопределённому методу Да
Добалвяете к аргументу значение по умолчанию Да
Вызываете приватный метод (через Reflection) Нет
Получаете доступ к частному свойству (через Reflection) Нет

Работа над кодом Symfony

Вы хотите помочь нам улучшить Symfony? Это прекрасно! Однако, пожалуйста, придерживайтесь правил, перечисленных ниже, чтобы гаранировать плавные обновления для наших пользователей.

Изменение интерфейсов

Эта таблица сообщает вам, какие изменения вам можно делать при работе с интерфейсами Symfony:

Тип изменения Изменение разрешено
Удалить полностью Нет
Изменить имя или пространство имён Нет
Добавить родительский интерфейс Да [2]
Удалить родительский интерфейс Нет
Методы  
Добавить метод Нет
Удалить метод Нет
Изменить имя Нет
Переместить родительский интерфейс Да
Добавить аргумент без значения по умолчанию Нет
Добавить аргумент со значением по умолчанию Нет
Удалить аргумент Да [3]
Добавить значение по умолчанию к аргументу Нет
Удалить значение по умолчанию из аргумента Нет
Добавить типизирование к аргументу Нет
Удалить типизирование аргумента Нет
Изменить тип аргумента Нет
Изменить тип возврата Нет
Константы  
Добавить константу Да
Удалить константу Нет
Изменить значение константы Да [1] [5]

Изменение классов

Эта таблица расскажет вамо том, какие изменения разрешены при работе с классами Symfony:

Тип изменения Изменение разрешено
Удалить полностью Нет
Сделать финальным Нет [6]
Сделать абстрактным Нет
Изменить имя или пространство имён Нет
Изменить родительский класс Да [4]
Добавить интерфейс Да
Удалить интерфейс Нет
Публичные свойства  
Добавить публичное свойство Да
Удалить публичное свойство Нет [7]
Уменьшить видимость Нет [7]
Переместить в родительский класс Да
Защищённые свойства  
Добавить защищённое свойство Да
Удалить защищённое свойство Нет
Уменьшить видимость Нет
Переместить в родительский класс Да
Приватные свойства  
Добавить приватное свойство Да
Удалить приватное свойство Да
Конструкторы  
Добавить конструктор без обязательных аргументов Да [1]
Удалить конструктор Нет
Уменьшить видимость публичного конструктора Нет
Уменьшить видимость защищённого конструктора Нет [7]
Переместить в родительский класс Да
Публичные методы  
Добавить публичный метод Да
Удалить публичный метод Нет
Изменить имя Нет
Уменьшить видимость Нет
Переместить в родительский класс Нет
Добавить аргумент без значения по умолчанию Нет
Добавить аргумент со значением по умолчанию Нет [7] [8]
Удалить аргумент Да [3]
Добавить к аргументу значение по умолчанию Нет [7] [8]
Удалить из аргумента значение по умолчанию Нет
Добавить типизрование к аргументу Нет [7] [8]
Удалить типизирование из аргумента Нет [7] [8]
Изменить тип аргумента Нет [7] [8]
Изменить тип возврата Нет [7] [8]
Защищённые методы  
Добавить защищённый метод Да
Удалить защищённый метод Нет [7]
Изменить имя Нет [7]
Уменьшить видимость Нет [7]
Переместить в родительский класс Да
Добавить аргумент без значения по умолчанию Нет [7]
Добавить аргумент со значением по умолчанию Нет [7] [8]
Удалить аргумент Да [3]
Добавить к аргументу значение по умолчанию Нет [7] [8]
Удалить из аргумента значение по умолчанию Нет [7]
Добавить типизрование к аргументу Нет [7] [8]
Удалить типизирование из аргумента Нет [7] [8]
Изменить тип аргумента Нет [7] [8]
Изменить тип возврата Нет [7] [8]
Приватные методы  
Добавить приватный метод Да
Удалить приватный метод Да
Изменить имя Да
Добавить аргумент без значения по умолчанию Да
Добавить аргумент со значением по умолчанию Да
Удалить аргумент Да
Добавить к аргументу значение по умолчанию Да
Удалить из аргумента значение по умолчанию Да
Добавить типизрование к аргументу Да
Удалить типизирование из аргумента Да
Изменить тип аргумента Да
Изменить тип возврата Да
Статичные методы  
Превратить нестатичный в статичный Нет [7] [8]
Превратить статичный в нестатичный Нет
Константы  
Добавить константу Да
Удалить константу Нет
Изменить значение константы Да [1] [5]
[1](1, 2, 3) Стоит избегать. Если же изменение сделано, оно должно быть задокументировано в файле UPGRADE.
[2]Добавленный родительский интерфейс не должен представлять никаких новых методов, не существующих в интерфейсе ранее.
[3](1, 2, 3) Только последний(ие) арумент(ы) метода могут быть удалены, так как PHP не волнуют дополнительные аргументы, которые вы передаёте методу.
[4]При изменении родительского класса, исходные родительский класс должен оставаться предшественником класса.
[5](1, 2) Значение константы может быть изменено только когда константы не используют в конфигурации (например, файлах Yaml и XML), так как они не поддерживают константы и должны жёстко кодировать значение. Например, константы имён событий не могут изменять значение без поломки ОС. Кроме того, если константа будет скорее всего использована в сериализованных объектах, значение константы не должно быть изменено.
[6]Позволено использование аннотации @final.
[7](1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) Разрешено, если класс финальный. Классы, получившие аннотацию @final после своего первого релиза, считаются финмальными в следующей полноценной версии. Изменение типа аргумента возможно только с родительским типом. Изменение типа возврата возможно только с дочерним типом.
[8](1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) Разрешено, если метод финальный. Метод, получивший @final после своего первого релиза, считается финмальным в следующей полноценной версии. Изменение типа аргумента возможно только с родительским типом. Изменение типа возврата возможно только с дочерним типом.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.