環境
PHP 7.2.21
CakePHP 2.10.18
MySQL 5.7.27
やりたいこと
CakePHPの処理中にて別のDBからデータを取得するためにDBの再接続を行いたい
前の記事にて別のDB設定ファイル読込み関数を用意したのでそれと合わせてControllerからDB切替えを行う
やったこと
ビヘイビアに別のDB情報を読み込む関数を用意し
ModelでactAsでビヘイビアを指定
Modelには更にDB再接続の関数を追加しておいてControllerで呼び出す
Model
Model/AppModel.php
<?php
App::uses('AppBaseModel', 'Model');
/**
* AppModel
*/
class AppModel extends AppBaseModel {
/**
* Hogeビヘイビアを使うためactAs追加
*/
public $actsAs = [
'Hoge',
];
/**
* 指定した設定ファイルを読込んでdataSourceを変更しDB再接続
* @param $dbFileName 読み込むdatabase.phpファイル名
* @param $dBConfig database.php内DBの参照情報
*/
public function connectAnotherDatabase($dbFileName, $dBConfig = 'default') {
if (!empty($dbFileName)) {
// $dbFileNameからDB情報呼び出し
$dbc = $this->readDatabaseValue($dbFileName);
// 前の処理でインスタンス化したClassを破棄
ConnectionManager::drop($dBConfig);
// DB再接続
$db = ConnectionManager::create($dBConfig, $dbc);
$db->reconnect($dbc);
$this->setDataSource($dBConfig);
return true;
} else {
return false;
}
}
}
Behavior
https://qiita.com/eltociear/items/55d45a35a8891c52c126
設定ファイル読み込み関数は↑記事と同じものを使用
Model/Behavior/HogeBehavior.php
<?php
/**
* Hoge behavior
*/
class HogeBehavior extends ModelBehavior {
/**
* 別のDB情報を環境database.phpから読込み
*
*@param Model $model
*@param string $dbFileName 読み込みたいdatabase.phpファイル名
*@return array 取得情報
*/
public function readDatabaseValue(Model $model, string $dbFileName) {
$cnt = 0;
$flg = false;
// 読み込みたいdatabase.phpのフルパス
$filePath = ROOT . DS . 'app' . DS . 'Config' . DS . $dbFileName;
if (file_exists($filePath)) {
$fdata = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($fdata as $line) {
$line = preg_replace("/( |,|')/", "", $line);
$data = explode('=>', $line);
if (strpos($line, 'public') !== false) {
$cnt++;
$flg = false;
}
if ($cnt == 1 && $flg == true) {
$result[$data[0]] = $data[1];
}
$flg = true;
}
}
return [
'datasource' => $result['datasource'],
'persistent' => $result['persistent'] === 'true' ? true : false,
'host' => $result['host'],
'login' => $result['login'],
'password' => $result['password'],
'database' => $result['database'],
'prefix' => $result['prefix'],
'encoding' => $result['encoding'],
];
}
}
Controller
別DBに再接続したい処理のあるControllerに設定ファイル名と上記で指定した関数呼び出しを記述
Controller/HogeController.php
// 再接続対象のDB情報がかかれた設定ファイル
$dbFileName = 'Neko.php';
// AppModelをextendsしたModelを使い別のDBに再接続
$this->Users->connectAnotherDatabase($dbFileName);
結果
変数で対象のDB設定ファイルを指定できるので再接続対象を動的にも指定できます