【Laminas】ServiceManagerを作る!

Laminas

どーも!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を操るコントローラーを作成していきます!

コメント

タイトルとURLをコピーしました