Composerの依存関係の問題(Symfonyサブパッケージの例)

以下の記事にあったComposerでの依存関係の問題。

読んだだけではよくわからなかったので確認してみます。

依存関係の問題

問題としては、結果としてあるパッケージの複数のバージョンに依存してしまうと依存関係を解決できない場合があるというものです。

例えば、あるパッケージがパッケージAのバージョン1.0に依存しており、別のパッケージがAのバージョン2.0に依存している場合、依存関係を解決できません。

例えば、フレームワークがあるパッケージを使っている場合、それの互換性のないバージョンに依存するパッケージを使うことはできなくなります。フレームワークの選択が使いたいパッケージを制約します。

また、そのような依存関係が解決できない場合、Composerがエラーを表示することが期待されます。普通はそうなるなずです。

しかし、場合によりComposerが検知できずにエラーにならないケースがあるというものです。

検知できないケース

まず、Symfony 2.3をインストールします。

$ symfony new my_application 2.3

 Downloading Symfony...

    4.55 MB/4.55 MB ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  100%

 Preparing project...

 ✔  Symfony 2.3.30 was successfully installed. Now you can:

    * Change your current directory to /Users/kenji/tmp/my_application

    * Configure your application in app/config/parameters.yml file.

    * Run your application:
        1. Execute the php app/console server:run command.
        2. Browse to the http://localhost:8000 URL.

    * Read the documentation at http://symfony.com/doc

そして、symfony/event-dispatcherを追加でインストールします。

$ cd my_application
$ composer require symfony/event-dispatcher 
Using version ^2.7 for symfony/event-dispatcher
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing symfony/event-dispatcher (v2.7.1)
    Loading from cache

Writing lock file
Generating autoload files
Updating the "app/config/parameters.yml" file
Clearing the cache for the dev environment with debug true
Installing assets using the hard copy option
Installing assets for Symfony\Bundle\FrameworkBundle into web/bundles/framework
Installing assets for Acme\DemoBundle into web/bundles/acmedemo
Installing assets for Sensio\Bundle\DistributionBundle into web/bundles/sensiodistribution

エラーなくv2.7.1がインストールできました。

さて、これで問題なく動作するのでしょうか?

$ composer dump-autoload --optimize  
Generating optimized autoload files
Warning: Ambiguous class resolution, "Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher" was found in both "/Users/kenji/tmp/my_application/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php" and "/Users/kenji/tmp/my_application/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php", the first will be used.
Warning: Ambiguous class resolution, "Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface" was found in both "/Users/kenji/tmp/my_application/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php" and "/Users/kenji/tmp/my_application/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php", the first will be used.
Warning: Ambiguous class resolution, "Symfony\Component\EventDispatcher\Event" was found in both "/Users/kenji/tmp/my_application/vendor/symfony/event-dispatcher/Event.php" and "/Users/kenji/tmp/my_application/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Event.php", the first will be used.
Warning: Ambiguous class resolution, "Symfony\Component\EventDispatcher\EventDispatcher" was found in both "/Users/kenji/tmp/my_application/vendor/symfony/event-dispatcher/EventDispatcher.php" and "/Users/kenji/tmp/my_application/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php", the first will be used.
Warning: Ambiguous class resolution, "Symfony\Component\EventDispatcher\EventDispatcherInterface" was found in both "/Users/kenji/tmp/my_application/vendor/symfony/event-dispatcher/EventDispatcherInterface.php" and "/Users/kenji/tmp/my_application/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcherInterface.php", the first will be used.
Warning: Ambiguous class resolution, "Symfony\Component\EventDispatcher\EventSubscriberInterface" was found in both "/Users/kenji/tmp/my_application/vendor/symfony/event-dispatcher/EventSubscriberInterface.php" and "/Users/kenji/tmp/my_application/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventSubscriberInterface.php", the first will be used.
Warning: Ambiguous class resolution, "Symfony\Component\EventDispatcher\GenericEvent" was found in both "/Users/kenji/tmp/my_application/vendor/symfony/event-dispatcher/GenericEvent.php" and "/Users/kenji/tmp/my_application/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/GenericEvent.php", the first will be used.
Warning: Ambiguous class resolution, "Symfony\Component\EventDispatcher\ImmutableEventDispatcher" was found in both "/Users/kenji/tmp/my_application/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php" and "/Users/kenji/tmp/my_application/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php", the first will be used.

警告が出てしまいました。

vendor/symfony/event-dispatcher/はバージョン2.7、vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/は2.3です。

これでちゃんと動くのでしょうか?バージョン2.7に依存しているコードは、怪しそうですね。

何故?

symfony/symfonyのcomposer.jsonが以下のようになっているからのようです。

"replace": {
    ...
    "symfony/event-dispatcher": "self.version",
    ...
},

まとめ

  • Composerが検知できない解決できない依存関係があります
  • サブパッケージには注意しましょう

関連

Date: 2015/07/07

Tags: php, composer, symfony