眠いっす。
Zend Frameworkを使ってWebアプリケーションを作ってて
「あー、DBへのクエリのログ取りたいなー」ってよくあると思います。
特にトランザクションの発生するクエリに関しては、Webプログラマとしては必需品だと思います。
方法はすべてのXXController内でクエリを発行する度に
<?phpと、簡単なサンプルを書くとこんな感じでしょうか。
// Zend_Db_Adapter_Abstractでクエリ発行
$adapter->query("INSERT INTO foo_table (column) VALUES ('value')");
// Zend_Db_Profiler
$profiler = $adapter->getProfiler();
$queries = $profiler->getQueryProfiles(Zend_Db_Profiler::INSERT);
if (is_array($queries)) {
foreach ($queries as $query) {
file_put_contents($filename, $query->getQuery());
}
}
ただ、これだとクエリを発行する度にZend_Db_Profilerを生成し、ログを取得しなければなりません。
面倒くさいです。
そんな面倒くさがりな貴方にはZend_Db_Adapter_Abstractを継承した自作クラスを作成することをオススメします。
例えばPostgreSQLを使っている場合は
<?phpこのようにinsert/update/deleteメソッドにログ処理を書いてZend_Db_Adapterの子クラスを作成します。
/**
* Zend_Db_Adapter_Pdo_Pgsqlを継承した自作アダプター
*/
class MyPdoPgsql extends Zend_Db_Adapter_Pdo_Pgsql {
/**
* @Override
*/
public function insert($table, array $bind) {
// 略 Zend_Db_Adapter_Pdo_Pgsql::insert()と同じ処理
// Zend_Db_Profilerでログる
$profiler = $adapter->getProfiler();
$queries = $profiler->getQueryProfiles(Zend_Db_Profiler::INSERT);
if (is_array($queries)) {
foreach ($queries as $query) {
file_put_contents($filename, $query->getQuery());
}
}
}
/**
* @Override
*/
public function update($table, array $bind, $where) {
// 略 Zend_Db_Adapter_Pdo_Pgsql::update()と同じ処理
// Zend_Db_Profilerでログる
$profiler = $adapter->getProfiler();
$queries = $profiler->getQueryProfiles(Zend_Db_Profiler::UPDATE);
if (is_array($queries)) {
foreach ($queries as $query) {
file_put_contents($filename, $query->getQuery());
}
}
}
public function delete($table, $where = '') {
// 以下同じ
}
}
あとはindex.php内の処理でZend_Db_Adapter_Abstractを生成するときに
<?phpのようにデフォルトアダプターをセットしておけば、全てOK!!
$db = new MyPdoPgsql($options);
Zend_Db_Table_Abstract::setDefaultAdapter($db);
基本的にZend FrameworkのクエリはZend_Db_Adapter_Abstractを経由して発行されるので、あとは自動でログを取ってくれます。
他にもトランザクションや例外処理も全てこの中に書けば、面倒なことを書かずに済みますね。
以上、面倒くさがり屋さんへ。
ありがとうございます。勉強になりました!
返信削除Zend_Db::factoryを使っている人に追記しときます。
■ブートファイル
$db = Zend_Db::factory($config->Database);
Zend_Db_Table::setDefaultAdapter('db');
■Configファイル
[Database]
adapter = "PDO_PGSQL"
params.adapterNamespace = "My_Db_Adapter"
params.host = "localhost"
params.username = "XXX"
params.password = "XXX"
params.dbname = "XXX"
■Adapterファイル
class My_Db_Adapter_Pdo_Pgsql extends Zend_Db_Adapter_Pdo_Pgsql
{
public function query($sql, $bind = array())
{
//if(preg_match('/^(insert|update|delete)/i',$sql)) ログ出力...
return parent::query($sql, $bind);
}
}