[PhalconPHP] MySQL Master-Slave(複数) 構成への接続設定

MySQLの master-slave 構成への接続設定。

公式ドキュメントだけだと分かりにくいかなー？って人がいるかもしれないということでメモ。
わかりにくかったらお気軽に質問してね。

##参考にした公式ドキュメント -  Working with Models - Setting multiple databases
https://phalcon-php-framework-documentation.readthedocs.org/en/latest/reference/models.html?highlight=selectReadConnection#setting-multiple-databases

##設定
###概要

編集するファイルは下記３つ。

```:構成
/app
  /config
     config.php
     service.php
  /models
     Base.php  // 名前は好きにしてOK
```

では順番に見ていきましょう。

###app/config/config.php
まずは設定ファイル

今回は
　　Master : 1
　　Slave : 3
の構成で書いてみました。
＃マルチMaster構成なんてやったことないけどね。

```php:app/config/config.php
<?php
   (中略)

   // masterの設定だよ
   $settings = array_merge(
        $settings,
        array(
            'mysql_master' => array(
                'adapter' => 'Mysql',
                'host' => '[hostname(master)]:[port]', // ex localhost:3306
                'username' => 'user',
                'password' => 'pass',
                'dbname' => 'database',
            ),
        )
    );

    // slave x3の設定だよ
    $slave1 = '[hostname(slave1)]:[port]'; // ex localhost:3316
    $slave2 = '[hostname(slave2)]:[port]'; // ex localhost:3326
    $slave3 = '[hostname(slave3)]:[port]'; // ex localhost:3336
    $mysqlSlaves = array(
        'mysql_slave1' => array(
            'adapter' => 'Mysql',
            'host' => $slave1,
                 'username' => 'user',
                'password' => 'pass',
                'dbname' => 'database',
        ),
        'mysql_slave2' => array(
            'adapter' => 'Mysql',
            'host' => $slave2,
                 'username' => 'user',
                'password' => 'pass',
                'dbname' => 'database',
        ),
        'mysql_slave3' => array(
            'adapter' => 'Mysql',
            'host' => $slave3,
                 'username' => 'user',
                'password' => 'pass',
                'dbname' => 'database',
        ),
    );

    // ちょっと回りくどい書き方しているのはここでslaveの台数をカウントしたいから。
    $settings = array_merge(
        $settings,
        $mysqlSlaves,
        array('mysql_slave_count' => count($mysqlSlaves))
    );

   (以下略)
```

これでconfigはOK

###app/config/service.php

次にservice.phpでPhalconのDI Containerにサービス登録しちゃいましょう。

　　Service : dbMasterにMySQL Masterへのコネクション
　　Service : dbSlaveにMySQL Slaveのいずれか１台へのコネクション

を登録します。


```php:app/config/service.php
<?php
   (中略)

// MySQL master
$di->set('dbMaster', function () use ($config) {
    return new DbAdapter(array(
        'host' => $config->mysql_master->host,
        'username' => $config->mysql_master->username,
        'password' => $config->mysql_master->password,
        'dbname' => $config->mysql_master->dbname
    ));
});
// MySQL slave
// slaveの中から１台ランダムに選択。randの上限指定にさっきのslave台数を使ってます。
$di->set('dbSlave', function () use ($config) {
    $slaveName = 'mysql_slave' . (String)rand(1, $config->mysql_slave_count);
    return new DbAdapter(array(
        'host' => $config[$slaveName]['host'],
        'username' => $config[$slaveName]['username'],
        'password' => $config[$slaveName]['password'],
        'dbname' => $config[$slaveName]['dbname']
    ));
});

   (以下略)
```

###app/models/Base.php

そして最後にMaster - Slaveを使う側。Modelです。
[公式ドキュメント](https://phalcon-php-framework-documentation.readthedocs.org/en/latest/reference/models.html?highlight=selectReadConnection#setting-multiple-databases "公式ドキュメント") - Working with Models - Setting multiple databases 

のこの辺
「But Phalcon offers you more flexibility, you can define the connection that must be used to ‘read’ and for ‘write’. This is specially useful to balance the load to your databases implementing a master-slave architecture:」
に書かれているように、

Model->initialize()メソッドあたりで読み書きに使用するServiceを指定してあげるといいと思います。
ここで言うServiceとはapp/config/service.phpでDIに登録したmaster or slaveのコネクションです。


書き込み時は

        $this->setWriteConnectionService('dbMaster');

に指定したServiceのコネクションを使う。

読み込み時は

        $this->setReadConnectionService('dbSlave');

に指定したServiceのコネクションを使う、


といった感じに指定できます。


コードはこんな感じ。

```php:app/models/Base.php
<?php

class Base extends Phalcon\Mvc\Model
{
    public function initialize()
    {
        $this->setWriteConnectionService('dbMaster');
        $this->setReadConnectionService('dbSlave');
    }
}
```

MySQLに接続したいModelには、上のBase.phpを継承させてます。
こんな感じ。


```php:app/models/Robots.php
<?php

class Robots extends Base
{
（略）
}
```


これで下記のようにコネクションを使い分けてくれるようになりました。

```php:
<?php

$robots = new Robots();

$robots->find(); // dbSlaveへ接続
（略）
$robots->save(); // dbMasterへ接続

```