ZendFramework3を使用して複数データベースに接続する方法[zend-db]

ZendFramework3の話です。

ZendFramework3では複数のデータベースに接続する処理を簡単に実装することが出来ます。例えばMySQLでレプリケーションを組んで、マスターは書き込み用・スレーブは読み込み用等のように、使用用途を分けている場合に便利です。

zend-dbを有効にする

複数のデータベースに接続する機能を利用するために、Zend\Dbを有効にします。

Zend\Dbを有効にするには「/config/application.config.php」の’modules’に「Zend\Db」を追加するのですが、’modules’は外部ファイル「/config/modules.config.php」を読み込んでいるのでそちらに記載します。

<?php
return [
    'Zend\Db', // ← Zend\Dbを追加
    'Zend\Form',
    'Zend\Router',
    'Zend\Session',
    'Zend\Validator',
    'Application',
];

Zend\Dbを有効にすることで、サービスマネージャーの「abstract_factories」に「Zend\Db\Adapter\AdapterAbstractServiceFactory」が登録されます。

この「Zend\Db\Adapter\AdapterAbstractServiceFactory」が複数データベース接続の機能を提供します。

データベース設定

データベース設定を「/config/autoload/local.php」に記載します。

<?php
return [
    'db' => [
        'adapters' => [
            'master' => [
                'driver'   => 'Mysqli',
                'database' => 'database_name',
                'username' => 'root',
                'password' => 'password',
                'hostname' => '192.168.1.1',
                'port'     => '',
                'charset'  => '',
            ],
            'slave' => [
                'driver'   => 'Mysqli',
                'database' => 'database_name',
                'username' => 'root',
                'password' => 'password',
                'hostname' => '192.168.1.2',
                'port'     => '',
                'charset'  => '',
            ],
        ],
    ],
];

マスターとスレーブの情報を設定しました。ここではアダプターの名前を’master’と’slave’にしましたが、名前は特に何でもいいです。但し、サービスマネージャを使って呼び出すため、他のサービスマネージャーの名前と重複してしまうと呼び出せなくなってしまうので、重複しないように注意しましょう。

アダプター取得

設定したアダプターを取得するにはサービスマネージャーを使用して、以下のように「/config/autoload/global.php」で設定したアダプター名を指定すれば取得できます。

// DB接続アダプタを取得
$master = $container->get('master');
$slave = $container->get('slave');

以上で簡単に複数データベースへの接続を行うことができるようになりました。

TableGatewayで使用

せっかくなので、マスターとスレーブのアダプタをひとつのテーブルオブジェクトで使用する方法を紹介します。ZendFrameworkではマスターとスレーブで接続アダプタを登録する機能が備わっています。

use Zend\Db\TableGateway;

// 「users」テーブルゲートウェイを作成
$userTable = new TableGateway\TableGateway('users', $master, [
    new TableGateway\Feature\MasterSlaveFeature($slave), // スレーブのアダプタを設定
    new TableGateway\Feature\RowGatewayFeature('id'),    // 取得結果をRowGatewayで取得(引数はプライマリーキー名)
]);

// スレーブサーバーから取得する
$userRows = $userTable->select();

foreach ($userRows as $user) {
    $user->name = 'あいうえお';
    // マスターサーバーへ書き込まれる
    $user->save();
}

マスターとスレーブで接続先を分けることで、ResultSet取得中にデータ更新してもエラーが発生しなくなります。

コメントを残す