Дата обновления перевода 2022-02-01

Обновление старшей версии (например, с 5.4.0 до 6.0.0)

Каждые два года Symfony выпускает новую старшую версию (меняется первая цифра). Эти релизы самые сложные в обновлении, так как им разрешено нарушать обратную совместимость. Однако, Symfony делает так, чтобы процесс обновления прошёл как можно более гладко.

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

В обновлении до старшей версии существует несколько шагов:

  1. Избавить ваш код от депрекаций;
  2. Обновить до новой старшей версии через Composer;
  3. Обновить ваш код, чтобы он работал с новой версией.

1) Избавить ваш код от депрекаций

Во время жизненного цикла релиза старшей версии, добавляются новые функции, а подписи методов и использование публичных API изменяются. Однако, младшие версии не должны содержать никаких изменений обратной совместимости. Чтобы добиться этого, “старый” код (например, функции, классы и т.д.) всё ещё будет работать, но будет помечен как осуждённый, обозначая, что он будет удалён или изменён в будущем, и что вам стоит перестать его использовать.

Когда выпускается старшая версия (например, 6.0.0), все устаревшие функции и особенности удаляются. Так что, если вы обновили ваш код так, чтобы он перестал использовать такие устаревшие функции в последней версии перед старшей (например, в 5.4.*), у вас не должно возникнуть проблем с обновлением. Это означает, что вы сначала должны обновиться до последней младшей версии (например, 5.4), чтобы вы могли увидеть все депрекации.

Чтобы помочь вам найти депрекации, уведомления вызываются каждый раз, когда вы используете устаревшую функцю. Когда вы посещаете ваше приложение в окружении разработки вашего браузера, эти уведомления отображаются в панели инструментов веб-разработки:

../_images/deprecations-in-profiler.png

В конце-концов, вы захотите перестать использовать устаревшую функциональность. Иногда предупреждение может сказать вам о том, что именно вам нужно изменить.

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

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

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

Депрекации в PHPUnit

Когда вы выполняете ваши тесты, используя PHPUnit, сообщения о депрекациях не отображаются. Чтобы помочь вам в этом, Symfony предоставляет мост PHPUnit. Этот мост покажет вам удобное резюме всех сообщений о возражениях в конце тестовго отчёта.

Всё, что вам нужно - это установить мост PHPUnit:

1
$ composer require --dev symfony/phpunit-bridge

Теперь вы можете начать исправлять уведомления:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# эта команда доступна после запуска "composer require --dev symfony/phpunit-bridge"
$ ./bin/phpunit
...

OK (10 тестов, 20 утверждений)

Оставшиеся сообщения о депрекациях (6)

Сервис "запроса" ("request") вызывает возражение и будет удалён в версии 3.0.
Добавьте типизирование для Symfony\Component\HttpFoundation\Request в параметры
вашего контроллера, чтобы вместо этого вернуть запрос: 6x
    3x in PageAdminTest::testPageShow from Symfony\Cmf\SimpleCmsBundle\Tests\WebTest\Admin
    2x in PageAdminTest::testPageList from Symfony\Cmf\SimpleCmsBundle\Tests\WebTest\Admin
    1x in PageAdminTest::testPageEdit from Symfony\Cmf\SimpleCmsBundle\Tests\WebTest\Admin

Как только вы исправите всё, команда окончится 0 (успех) и вы закончили!

Caution

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

2) Обновить до новой старшей версии через Composer

Когда ваш код будет избавлен от депрекаций, вы можете обновить библиотеку Symfony через Composer, модифицировав ваш файл composer.json, и изменив все библиотеки, которые начинаются с symfony/ на новую старшую версию:

{

“…”: “…”,

“require”: {

  • “symfony/cache”: “5.4.*”,
  • “symfony/cache”: “6.0.*”,
  • “symfony/config”: “5.4.*”,
  • “symfony/config”: “6.0.*”,
  • “symfony/console”: “5.4.*”,
  • “symfony/console”: “6.0.*”, “…”: “…”,

    “…”: “Несколько библиотек, начинающихся с symfony/,

    следуют собственной схеме версионирования. Вам не нужно обновлять эти версии: вы можете обновить их независимо, когда захотите”,

    “symfony/monolog-bundle”: “^3.5”,

}, “…”: “…”,

}

Внизу вашего файла composer.json, в блоке extra, вы можете найти настройку данных для версии Symfony. Убедитесь в том, что обновили и ее. Например, ирзмените ее на 6.0.*, чтобы обновиться до версии Symfony 6.0:

1
2
3
4
5
6
7
  "extra": {
      "symfony": {
          "allow-contrib": false,
-       "require": "5.4.*"
+       "require": "6.0.*"
      }
  }

Далее, используйте Composer, чтобы скачать новые версии библиотек:

1
$ composer update "symfony/*"

Dependency Errors

If you get a dependency error, it may mean that you also need to upgrade other libraries that are dependencies of the Symfony libraries. To allow that, pass the --with-all-dependencies flag:

1
$ composer update "symfony/*" --with-all-dependencies

This updates symfony/* and all packages that those packages depend on. By using tight version constraints in composer.json, you can control what versions each library upgrades to.

If this still doesn’t work, your composer.json file may specify a version for a library that is not compatible with the newer Symfony version. In that case, updating that library to a newer version in composer.json may solve the issue.

Or, you may have deeper issues where different libraries depend on conflicting versions of other libraries. Check your error message to debug.

Another issue that may happen is that the project dependencies can be installed on your local computer but not on the remote server. This usually happens when the PHP versions are different on each machine. The solution is to add the platform config option to your composer.json file to define the highest PHP version allowed for the dependencies (set it to the server’s PHP version).

Upgrading other Packages

You may also want to upgrade the rest of your libraries. If you’ve done a good job with your version constraints in composer.json, you can do this safely by running:

1
$ composer update

Caution

Beware, if you have some unspecific version constraints in your composer.json (e.g. dev-master), this could upgrade some non-Symfony libraries to new versions that contain backwards-compatibility breaking changes.

3) Updating Recipes

Over time - and especially when you upgrade to a new version of a library - an updated version of the recipe may be available. These updates are usually minor - e.g. new comments in a configuration file - but it’s a good idea to keep your files in sync with the recipes.

Symfony Flex provides several commands to help upgrade your recipes. Be sure to commit any unrelated changes you’re working on before starting:

New in version 1.18: The recipes:update command was introduced in Symfony Flex 1.18.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# choose an outdated recipe to update
$ composer recipes:update

# update a specific recipe
$ composer recipes:update symfony/framework-bundle

# see a list of all installed recipes and which have updates available
$ composer recipes

# see detailed information about a specific recipes
$ composer recipes symfony/framework-bundle

The recipes:update command is smart: it looks at the difference between the recipe when you installed it and the latest version. It then creates a patch and applies it to your app. If there are any conflicts, you can resolve them like a normal git conflict and commit like normal.

3) Обновить ваш код, чтобы он работал с новой версией

В некоторых редких ситуациях, следующая старшая версия может содержать нарушения обратной совместимости. Не забудьте прочитать UPGRADE-X.0.md (где X - это новая старшая версия), включенный в хранилище Symfony, чтобы узнать о любых нарушениях обратной совместимости, на которые вам стоит обратить внимание.

Обновление до Symfony 6: Добавление нативных типов возвращаемых значений

New in version 5.4: Проверка типа возвращаемого значения и исправление функций были представлены в Symfony 5.4.

Symfony 6 будет поставляться с нативными типами возвращаемых значений PHP (почти) ко всем методам.

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

Когда включен режим отладки (обычно в окружениях разработки и тестирования), Symfony будет выдавать депрекации для каждой несовместимой декларации методов. Например, метод UserInterface::getRoles() в Symfony 6 будет иметь тип возвращаемого значения array. В Symfony 5.4, вы получите сообщение о депрекации, и должны будете добавить декларацию типа возвращаемого значения к вашему методу getRoles().

Чтобы помочь с этим, Symfony предоставляет скрипт, который может добавлять эти типы возвращаемых значений за вас автоматически. Убедитесь в том, что вы установили компонент symfony/error-handler. После этого, сгенерируйте полное отображение классов, используя Composer, и выполните скрипт, чтобы выполнить перебор и исправить все несовместимые методы:

1
2
3
4
5
6
7
# Убедитесь, что "exclude-from-classmap" не заполнен в вашем "composer.json". Затем сбросьте автозагрузчик:

# "-o" - это важно! Это заставляет Composer найти все классы
$ composer dump-autoload -o

# исправьте все декларации несовместимых методов
$ ./vendor/bin/patch-type-declarations

Tip

Эта функция не ограничивается пакетами Symfony. Она также поможет вам добавлять типы и готовиться к другим зависимостям в вашем проекте.

Поведения этого скрипта можно изменить, используя переменную окружения SYMFONY_PATCH_TYPE_DECLARATIONS. Значение этой переменной окружения url-зашифровано (например, param1=value2&param2=value2), и доступны следующие параметры:

force

Включает исправление типов возвращаемых значений, значение должно быть:

  • 2, чтобы добавить все возможные типы возвращаемых значений (по умолчанию рекомендовано для приложений);
  • 1, чтобы добавить типы возвращаемых значений только к тестам, финальным, внутренним или приватным методам;
  • phpdoc, чтобы добавить только аннотации docblock @return к несовместимым методам, или #[\ReturnTypeWillChange], если оно вызвано PHP-движком.
php
Целевая версия PHP - например, 7.1 не генерирует типы “object” (которые были представлены в 7.2). По умолчанию это приравнивается к PHP-версии, используемой при выполнении скрипта.
deprecations
Установите 0, чтобы отключить депрекации. Иначе, возникнет уведомление депрекации, когда дочернему классу не будет хватать типа возвращаемого значения, в то время как родительский класс будет объявлять аннотацию @return (по умолчанию - 1).

Если есть какие-то конкретные файлы, которые нужно игнорировать, вы можете установить переменную окружения SYMFONY_PATCH_TYPE_EXCLUDE как регулярное выражение. Это регулярное выражение будет сопоставлено с полным путем к классу, и каждый совпадающий путь будет проигнорирован (например, SYMFONY_PATCH_TYPE_EXCLUDE="/tests\/Fixtures\//"). Классы в каталоге vendor/ всегда будут игнорироваться.

Tip

Скрипту неважен стиль кода. Запустите свой исправитель стиля кода, или PHP CS Fixer с правилами phpdoc_trim_consecutive_blank_line_separation, no_superfluous_phpdoc_tags и ordered_imports, после исправления типов.

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