JavaScriptを有効にしてください

【PHP】Phalcon DI の get と getShared の違い

 ·  ☕ 2 分で読めます

【Phalcon】DI の get と getShared の違いを整理する

Phalcon の DI コンテナを使っていると、$di->get()$di->getShared() のどちらを使うべきか迷う場面があります。

結論だけ先に書くと次のとおりです。

  • get() は都度インスタンスを解決する(非共有サービスなら毎回新規生成)
  • getShared() は同じインスタンスを使い回す

この違いを理解しておくと、不要なオブジェクト生成や状態の混乱を防げます。

get と getShared の違い

まずは最小コードです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$di = new \Phalcon\Di\FactoryDefault();

$di->set('requestId', function () {
    return new stdClass();
});

$a = $di->get('requestId');
$b = $di->get('requestId');

var_dump($a === $b); // false(毎回新しいインスタンス)

同じサービスを getShared() で取得すると、結果は変わります。

1
2
3
4
$a = $di->getShared('requestId');
$b = $di->getShared('requestId');

var_dump($a === $b); // true(同じインスタンス)

使い分けの目安

get() を使う場面

  • 毎回クリーンなインスタンスが必要なとき
  • 内部状態を持つクラスを使い回したくないとき

例:

  • 使い捨ての DTO
  • リクエストごとに都度生成したい軽量サービス

getShared() を使う場面

  • 同一リクエスト内で同じ依存を再利用したいとき
  • 接続コストが高いオブジェクトを使い回したいとき

例:

  • DB 接続
  • 設定オブジェクト
  • ロガー

setShared との関係

setShared() で登録したサービスは共有サービスとして扱われます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$di->setShared('config', function () {
    return [
        'appName' => 'sample',
    ];
});

$x = $di->get('config');
$y = $di->get('config');

var_dump($x === $y); // true

つまり「共有サービスとして登録するか」「取得時に共有取得するか」の 2 つで挙動が決まります。

実務でのおすすめ方針

迷ったら、次のように決めると運用しやすいです。

  • 原則 setShared() + get() で統一し、共有する意図を登録時に明示する
  • 都度生成したいサービスのみ set() で登録する
  • getShared() は「この場面では必ず共有にしたい」という意図が強いときに使う

まとめ

  • get() は非共有サービスなら毎回新規インスタンス
  • getShared() は同じインスタンスを再利用
  • setShared() を使うと get() でも共有インスタンスを返す

DI の解決ルールをそろえておくと、バグ調査や保守がかなり楽になります。

参考文献

共有

こぴぺたん
著者
こぴぺたん
Copy & Paste Engineer