SilexのServiceControllerServiceProvider使うと、URLマッチ後にコントローラサービスのインスタンスが生成されて、普通にマウントしてるとマッチしようがしまいが必ずインスタンス生成されるんだよなーという認識でいたのですが、本当にそうなってるか確認しました。とりあえずあってそうですが、せっかくなのでメモ。
コードはmatsu-chara/SilexLazyControlerLoadSample · GitHubに有ります。
コントローラサービスの登録などが面倒なのでAPIのひな形としてsilex-simple-restを使用してます。 詳しくは前回を参照。
調べ方
dummy, dummy2, api/v1/dummyという3つのAPIを用意。全部("dummy"という文字列を返すだけのAPI) それぞれのコントローラクラスのコンストラクトメソッドに
public function __construct(Logger $monolog) { $this->monolog = $monolog; $this->monolog->addInfo("dummy constructed"); }
とログを仕込む。
dummy/, dummy2/のコントローラはsrc/app.phpで
$app->mount('/dummy', new App\Controllers\DummyControllerProvider($app['monolog'])); $app->mount('/dummy2', new App\Controllers\Dummy2ControllerProvider($app['monolog']));
と登録。
api/v1/dummy/
のコントローラはsrc/App/Controllers/RoutesLoader.php
で$api->get('/dummy', "lazyDummy.controller:getDummy");
のように登録。
結果
/* * API:dummy/ * dummyコントローラのみが必要だがdummy, dummy2コントローラがインスタンス化されている。 * lazyDummy, lazyDummy2は不要なので生成されない。 */ [2014-01-12 02:10:34] application.INFO: Dummy constructed [] [] [2014-01-12 02:10:34] application.INFO: Dummy2 constructed [] [] [2014-01-12 02:10:34] application.INFO: Matched route "_dummyGET_" (parameters: "_controller": "{}", "_route": "_dummyGET_") [] [] [2014-01-12 02:10:34] application.INFO: > GET /dummy/ [] [] [2014-01-12 02:10:34] application.INFO: < 200 [] [] /* * API:dummy2/ * 同様にdummy, dummy2がインスタンス化されている * lazyDummy, lazyDummy2は不要なので生成されない。 */ [2014-01-12 02:10:35] application.INFO: Dummy constructed [] [] [2014-01-12 02:10:35] application.INFO: Dummy2 constructed [] [] [2014-01-12 02:10:35] application.INFO: Matched route "_dummy2GET_" (parameters: "_controller": "{}", "_route": "_dummy2GET_") [] [] [2014-01-12 02:10:35] application.INFO: > GET /dummy2/ [] [] [2014-01-12 02:10:35] application.INFO: < 200 [] [] /* * API:api/v1/dummy/ * dummy, dummy2に加え * ルートマッチングが行われた後にlazyDummyコントローラがインスタンス化されている。 * lazyDummy2は不要なので生成されない。 */ [2014-01-12 02:10:41] application.INFO: Dummy constructed [] [] [2014-01-12 02:10:41] application.INFO: Dummy2 constructed [] [] [2014-01-12 02:10:41] application.INFO: Matched route "_api_v1GET_dummy" (parameters: "_controller": "lazyDummy.controller:getDummy", "_route": "_api_v1GET_dummy") [] [] [2014-01-12 02:10:41] application.INFO: > GET /api/v1/dummy [] [] [2014-01-12 02:10:41] application.INFO: lazyDummy constructed [] [] [2014-01-12 02:10:41] application.INFO: getDummy [] [] [2014-01-12 02:10:41] application.INFO: < 200 [] [] /* * API:api/v1/dummy2/ * dummy, dummy2に加え * ルートマッチングが行われた後にlazyDummy2コントローラがインスタンス化されている。 * lazyDummyは不要なので生成されない。 */ [2014-01-12 02:10:43] application.INFO: Dummy constructed [] [] [2014-01-12 02:10:43] application.INFO: Dummy2 constructed [] [] [2014-01-12 02:10:43] application.INFO: Matched route "_api_v1GET_dummy2" (parameters: "_controller": "lazyDummy2.controller:getDummy", "_route": "_api_v1GET_dummy2") [] [] [2014-01-12 02:10:43] application.INFO: > GET /api/v1/dummy2 [] [] [2014-01-12 02:10:43] application.INFO: lazyDummy2 constructed [] [] [2014-01-12 02:10:43] application.INFO: getDummy [] [] [2014-01-12 02:10:43] application.INFO: < 200 [] []
ってことで普通にmountすると全部のコントローラのインスタンスが生成されるけど、ServiceControllerServiceProviderを使うと使うやつだけで済む上に、コントローラの独立性も上がるよ!というお話でした。
うーんパフォーマンスにどう影響するのかはかりたいけどはかるものがない(´・_・`)