どーも!marusukeです!
今回は前回記事(【Laminas】モデルを作る!)の続きで、ServiceManagerを作っていきます!
では、進めていきましょう!
ServiceManagerとは?
誤解を恐れず簡単に説明すると、module内に作ったクラスをインスタンス化し、そのインスタンスを常に同じ形で呼び出す便利ツールのことです。(参考:公式ドキュメントのServiceManager部分)
ServiceManagerにはサービスロケーターパターンが使われているとのことです。サービスロケーターパターンについての解説は割愛します。
なぜServiceManagerを書くのか
前回の記事(【Laminas】モデルを作る!)で書いた、AlbumTable.phpを常に同じ形でインスタンス化するためです。
実際に書いていきましょう!
記述場所は、module/Album/src/Module.php
です。
<?php
namespace Album;
// 以下の3行を追加してください
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Db\ResultSet\ResultSet;
use Laminas\Db\TableGateway\TableGateway;
use Laminas\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface
{
public function getConfig()
{
return include __DIR__ . '/../config/module.config.php';
}
// 以下のgetServiceConfig()メソッドを追加してください
public function getServiceConfig()
{
return [
'factories' => [
Model\AlbumTable::class => function($container) {
$tableGateway = $container->get(Model\AlbumTableGateway::class);
return new Model\AlbumTable($tableGateway);
},
Model\AlbumTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
],
];
}
}
このgetServiceConfig()の概要を説明すると、
'factories' => [
Aのクラス::class => このような形で呼び出すよ!,
Bのクラス::class => このような形で呼び出すよ!
];
というようなことが書いてあります。
つまり、今回の場合だと、
'factories' => [
Model\AlbumTable::class => クロージャ関数{return new AlbumTable(...)},
Model\AlbumTableGateway::class => クロージャ関数{return new TableGateway(...)}
];
となっています。
①Model\AlbumTable::class =>について
中身を詳しく見ると、
Model\AlbumTable::class => function($container) {
$tableGateway = $container->get(Model\AlbumTableGateway::class);
return new Model\AlbumTable($tableGateway);
},
となっています。クロージャ内を1つずつ説明していきますね!
クロージャの引数は、「$container」は、サービスロケーターパターンのコンテナオブジェクト(LaminasのServiceManagerオブジェクトのこと)ですね!
2行目の、$tableGateway = $container->get(Model\AlbumTableGateway::class);
では$container内のModel\AlbumTableGatewayクラスを取得しています。
3行目の、return new Model\AlbumTable($tableGateway);は、
戻り値として、Model\AlbumTableクラスに$containerを注入し、インスタンス化していますね!
つまり、AlbumTableクラスを呼び出すときは、AlbumTableGatewayクラスを注入してインスタンス化して呼び出してね!ということを、ServiceManagerがModuleManegerに教えています。
ここで一つ疑問が浮かびました。
AlbumTableGatewayクラスとは何者??ということです。
AlbumTableGatewayクラスを説明していきます。
②Model\AlbumTableGateway::class =>について
getServiceConfig()メソッド内のModel\AlbumTableGateway::class => …の部分です。
Model\AlbumTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
簡単に説明すると、AlbumTableGatewayクラスは、データベースとの接続方法や、データベースから取得したデータを表示できるようにデータの形を設定するクラスになります。
順を追って説明していきますね!
クロージャ内の、1行目の$dbAdapter = $container->get(AdapterInterface::class);は、$container内のAdapterInterfaceからデータベースの接続設定を取得ししています。
2行目の$resultSetPrototype = new ResultSet();では、resultSetオブジェクトを作り、
3行目の$resultSetPrototype->setArrayObjectPrototype(new Model\Album());で、AlbumエンティティであるAlbum.phpをインスタンス化し注入することで、今回扱うデータである、id、artist、titleを受け取れるオブジェクト(プロトタイプパターン)に変形させています。
4行目のreturn new TableGateway(‘album’, $dbAdapter, null, $resultSetPrototype);では、LaminasサブコンポーネントであるTableGatewayオブジェクトを返しています。(LaminasサブコンポーネントTableGatewayについて、必要な引数などご確認ください。)
これで、AlbumTableGatewayクラスがクロージャによって作成されるようになりました。
Modelが完成しました!
今回はここまでです。お疲れ様でした!
次は、Modelを操るコントローラーを作成していきます!
コメント