Laravel4、パッケージがPHP5.3で動かない時
タグ: Laravel4
あるパッケージのPHP要件が5.3以上になっているので、5.3環境で使えると思っても、エラーになる場合、本当は5.4以上が必要な場合が時々見受けられます。
例えばcomposer.jsonには以下のように書いてあります。
"require": { "php": ">=5.3.0", "illuminate/support": "4.0.x" },
こう書かれると、packagistの表示もこれに基づいて表示されるため、5.3で動くと信じこんでしまいます。
もしコードの中に配列のショートカット記法が使ってあれば、明確にこの依存指定が間違っているとすぐ分かります。
return [ 'name' => 'Tonaka', 'age' => 87 ];
しかし、5.4の上で開発しておいて、5.3でも対応させようとこの記法を避けて書かれると、いきなりエラーでビビることもあるでしょう。
たいてい、クロージャーの中に$thisを持ち込んでいるのが原因です。私も、5.3で動くはずのコードが動かなかったり、サービスプロバーダーの中の定義がエラーになってしまっていたりで、首をひねりました。
よくあるのが、バインドのコードです。
$this->app->bind("chat.emitter", function() { return new EventEmitter(); }); $this->app->bind("chat.chat", function() { return new Chat( $this->app->make("chat.emitter") ); });
今訳している、リアルタイムチャットのコードです。:D サービスプロバーダーの中で結合している部分です。
これも、PHP 5.3以上と指定していますが、実際は5.4以上でないと動きません。(これ以外にも、たくさん[...]を使っているので、何が起きているか把握はしやすかったです。)5.3ではクロージャーの中に$thisを持ち込むとコンテキストがどうのこうのとFatalエラーになります。
5.3を使用している方で、サービスプロバイダー周りのIoC登録の部分が、参考にしている書籍やWebチュートリアル通りにやってもうまく動かなくて、悩んでいる方がいるかも知れませんね。
実際は、Laravelに組み込まれているサービスプロバイダーを参考にしてもらい、以下のように書くと5.3でも動作します。
$this->app->bind("chat.emitter", function() { return new EventEmitter(); }); $this->app->bind("chat.chat", function($app) { return new Chat( $app->make("chat.emitter") ); });
IoCコンテナでもあるAppクラスのインスタンスが、バインド時のクロージャーには渡されますので、それを利用して結合してください。