Upgrading a Third-Party Bundle for a Major Symfony Version

Symfony 3 was released in November 2015. Although this version doesn't contain any new features, it removes all the backward compatibility layers included in the previous 2.8 version. If your bundle uses any deprecated feature and it's published as a third-party bundle, applications upgrading to Symfony 3 will no longer be able to use it.

Symfony 3 は 2015 年 11 月にリリースされました。このバージョンには新機能は含まれていませんが、以前の 2.8 バージョンに含まれていた下位互換性レイヤーがすべて削除されています。バンドルが非推奨の機能を使用し、それがサードパーティのバンドルとして公開されている場合、Symfony 3 にアップグレードするアプリケーションはそれを使用できなくなります。

Allowing to Install Symfony 3 Components

Most third-party bundles define their Symfony dependencies using the ~2.N or ^2.N constraints in the composer.json file. For example:

ほとんどのサードパーティ バンドルは、composer.json ファイルの ~2.N または ^2.N 制約を使用して Symfony の依存関係を定義します。例えば:
1
2
3
4
5
6
7
{
    "require": {
        "symfony/framework-bundle": "~2.7",
        "symfony/finder": "~2.7",
        "symfony/validator": "~2.7"
    }
}

These constraints prevent the bundle from using Symfony 3 components, which means the bundle cannot be installed in a Symfony 3 based application. Thanks to the flexibility of Composer dependencies constraints, you can specify more than one major version by replacing ~2.N by ~2.N|~3.0 (or ^2.N by ^2.N|~3.0).

これらの制約により、バンドルは Symfony 3 コンポーネントを使用できなくなります。つまり、バンドルを Symfony 3 ベースのアプリケーションにインストールすることはできません。 Composer 依存関係制約の柔軟性のおかげで、~2.N を ~2.N|~3.0 に (または ^2.N を ^2.N|~3.0 に) 置き換えることで、複数のメジャー バージョンを指定できます。

The above example can be updated to work with Symfony 3 as follows:

上記の例は、次のように Symfony 3 で動作するように更新できます。
1
2
3
4
5
6
7
{
    "require": {
        "symfony/framework-bundle": "~2.7|~3.0",
        "symfony/finder": "~2.7|~3.0",
        "symfony/validator": "~2.7|~3.0"
    }
}

Tip

ヒント

Another common version constraint found on third-party bundles is >=2.N. You should avoid using that constraint because it's too generic (it means that your bundle is compatible with any future Symfony version). Use instead ~2.N|~3.0 or ^2.N|~3.0 to make your bundle future-proof.

サードパーティのバンドルに見られる別の一般的なバージョン制約は >=2.N です。この制約は一般的すぎるため、使用しないでください (バンドルが将来の Symfony バージョンと互換性があることを意味します)。代わりに ~2.N|~3.0 または ^2.N|~3.0 を使用して、バンドルを将来的に保証します。

Look for Deprecations and Fix Them

Besides allowing users to use your bundle with Symfony 3, your bundle must stop using any feature deprecated by the 2.8 version because they are removed in 3.0 (you'll get exceptions or PHP errors). The easiest way to detect deprecations is to install the symfony/phpunit-bridge package and then run the test suite.

ユーザーが Symfony 3 でバンドルを使用できるようにするだけでなく、バ​​ージョン 2.8 で非推奨になった機能は 3.0 で削除されているため、バンドルはそれらの使用を停止する必要があります (例外または PHP エラーが発生します)。非推奨を検出する最も簡単な方法は、symfony/phpunit-bridge パッケージをインストールしてからテスト スイートを実行することです。

First, install the component as a dev dependency of your bundle:

まず、コンポーネントをバンドルの dev 依存関係としてインストールします。
1
$ composer require --dev symfony/phpunit-bridge

Then, run your test suite and look for the deprecation list displayed after the PHPUnit test report:

次に、テスト スイートを実行し、PHPUnit テスト レポートの後に表示される非推奨リストを探します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# this command is available after running "composer require --dev symfony/phpunit-bridge"
$ ./bin/phpunit

# ... PHPUnit output

Remaining deprecation notices (3)

The "pattern" option in file ... is deprecated since version 2.2 and will be
removed in 3.0. Use the "path" option in the route definition instead ...

Twig Function "form_enctype" is deprecated. Use "form_start" instead in ...

The Symfony\Bundle\SecurityBundle\SecurityContext class is deprecated since
version 2.6 and will be removed in 3.0. Use ...

Fix the reported deprecations, run the test suite again and repeat the process until no deprecation usage is reported.

報告された非推奨を修正し、テスト スイートを再度実行して、非推奨の使用が報告されなくなるまでプロセスを繰り返します。

Useful Resources

There are several resources that can help you detect, understand and fix the use of deprecated features:

廃止された機能の使用を検出、理解、修正するのに役立つリソースがいくつかあります。
Official Symfony Guide to Upgrade from 2.x to 3.0
The full list of changes required to upgrade to Symfony 3.0 and grouped by component.
Symfony 3.0 および groupedby コンポーネントへのアップグレードに必要な変更の完全なリスト。
SensioLabs DeprecationDetector
It runs a static code analysis against your project's source code to find usages of deprecated methods, classes and interfaces. It works for any PHP application, but it includes special detectors for Symfony applications, where it can also detect usages of deprecated services.
プロジェクトのソース コードに対して静的コード分析を実行し、非推奨のメソッド、クラス、およびインターフェイスの使用法を見つけます。どの PHP アプリケーションでも機能しますが、Symfony アプリケーション用の特別な検出機能が含まれており、非推奨のサービスの使用も検出できます。
Symfony Upgrade Fixer
It analyzes Symfony projects to find deprecations. In addition it solves automatically some of them thanks to the growing list of supported "fixers".
Symfony プロジェクトを分析して非推奨を見つけます。さらに、サポートされている「フィクサー」のリストが増えているため、それらのいくつかを自動的に解決します。

Testing your Bundle in Symfony 3

Now that your bundle has removed all deprecations, it's time to test it for real in a Symfony 3 application. Assuming that you already have a Symfony 3 application, you can test the updated bundle locally without having to install it through Composer.

バンドルがすべての非推奨を取り除いたので、Symfony 3 アプリケーションで実際にテストする時が来ました。 Symfony 3 アプリケーションが既にあると仮定すると、更新されたバンドルをローカルでテストでき、Composer を介してインストールする必要はありません。

If your operating system supports symbolic links, instead point the appropriate vendor directory to your local bundle root directory:

オペレーティング システムがシンボリック リンクをサポートしている場合は、代わりに適切なベンダー ディレクトリをローカル バンドル ルート ディレクトリにポイントします。
1
$ ln -s /path/to/your/local/bundle/ vendor/you-vendor-name/your-bundle-name

If your operating system doesn't support symbolic links, you'll need to copy your local bundle directory into the appropriate directory inside vendor/.

オペレーティング システムがシンボリック リンクをサポートしていない場合は、ローカル バンドル ディレクトリを vendor/ 内の適切なディレクトリにコピーする必要があります。

Update the Travis CI Configuration

In addition to running tools locally, it's recommended to set-up Travis CI service to run the tests of your bundle using different Symfony configurations. Use the following recommended configuration as the starting point of your own configuration:

ツールをローカルで実行することに加えて、さまざまな Symfony 構成を使用してバンドルのテストを実行するように Travis CI サービスをセットアップすることをお勧めします。独自の構成の開始点として、次の推奨構成を使用します。
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
language: php
php:
    - 5.3
    - 5.6
    - 7.0

matrix:
    include:
        - php: 5.3.3
          env: COMPOSER_FLAGS='--prefer-lowest --prefer-stable' SYMFONY_DEPRECATIONS_HELPER=max[total]=999999
        - php: 5.6
          env: SYMFONY_VERSION='2.7.*'
        - php: 5.6
          env: SYMFONY_VERSION='2.8.*'
        - php: 5.6
          env: SYMFONY_VERSION='3.0.*'
        - php: 5.6
          env: SYMFONY_VERSION='3.1.*'
        - php: 5.6
          env: DEPENDENCIES='dev' SYMFONY_VERSION='3.2.*@dev'

before_install:
    - composer self-update
    - if [ "$DEPENDENCIES" == "dev" ]; then perl -pi -e 's/^}$/,"minimum-stability":"dev"}/' composer.json; fi;
    - if [ "$SYMFONY_VERSION" != "" ]; then composer --no-update require symfony/symfony:${SYMFONY_VERSION}; fi;

install: composer update $COMPOSER_FLAGS

script: phpunit

Updating your Code to Support Symfony 2.x and 3.x at the Same Time

The real challenge of adding Symfony 3 support for your bundles is when you want to support both Symfony 2.x and 3.x simultaneously using the same code. There are some edge cases where you'll need to deal with the API differences.

バンドルに Symfony 3 サポートを追加する際の本当の課題は、同じコードを使用して Symfony 2.x と 3.x の両方を同時にサポートしたい場合です。 API の違いに対処する必要がある特殊なケースがいくつかあります。

Before diving into the specifics of the most common edge cases, the general recommendation is to not rely on the Symfony Kernel version to decide which code to use:

最も一般的なエッジケースの詳細に飛び込む前に、一般的な推奨事項は、使用するコードを決定するために Symfony カーネルのバージョンに依存しないことです。
1
2
3
4
5
if (Kernel::VERSION_ID < 20800) {
    // code for Symfony 2.x
} else {
    // code for Symfony 3.x
}

Instead of checking the Symfony Kernel version, check the version of the specific component. For example, the OptionsResolver API changed in its 2.6 version by adding a setDefined() method. The recommended check in this case would be:

Symfony カーネルのバージョンを確認する代わりに、特定のコンポーネントのバージョンを確認してください。たとえば、OptionsResolver API は、2.6 バージョンで setDefined() メソッドを追加することで変更されました。この場合に推奨されるチェックは次のとおりです。
1
2
3
4
5
6
7
use Symfony\Component\OptionsResolver\OptionsResolver;

if (!method_exists(OptionsResolver::class, 'setDefined')) {
    // code for the old OptionsResolver API
} else {
    // code for the new OptionsResolver API
}

Tip

ヒント

There is one case when you actually can rely on the Symfony\Component\HttpKernel\Kernel::VERSION_ID constant: when trying to detect the version of the symfony/http-kernel component, because it is the component where this constant is defined.

実際に Symfony\Component\HttpKernel\Kernel::VERSION_ID 定数に依存できるケースが 1 つあります: symfony/http-kernel コンポーネントのバージョンを検出しようとするときです。これは、この定数が定義されているコンポーネントであるためです。