ORM(データベースの中身をオブジェクトにマッピングする仕組み)は便利であり、Laravelに入っているEloquent ORMはとてもとても便利で開発を簡単にしてくれます。しかしながらORMを介して記述をしていると実際に発行されているSQL命令がコードから読み取りにくいものになります。グローバルスコープにより暗黙的に条件を追加する、User::create($request->all())だけでINSERTを済ませる、といったことをするならばなおさらです。デバッグのためには実際に発行されているクエリをロギングしたいものです。
LaravelのDB接続クラスには次のlistenメソッドが備わっており、これを用いることでクエリの発行の度にlistenイベントを発生させます。
データベース:利用開始 5.6 Laravel#クエリイベントのリッスン
/** * Register a database query listener with the connection. * データベースクエリリスナを接続に登録する。 * * @param \Closure $callback * @return void */ public function listen(Closure $callback) { if (isset($this->events)) { $this->events->listen(Events\QueryExecuted::class, $callback); } }
このlistenメソッドに渡す関数にクエリをロギングする関数にし、その記述を上記リンクにある様にアプリケーションサービスの初期処理で呼び出されるapp\Providers\AppServiceProviderのbootメソッドに行います。
class AppServiceProvider extends ServiceProvider { /** * アプリケーションサービスの初期処理 * @return void */ public function boot() { DB::listen(function (QueryExecuted $query) { Log::debug(str_replace_array('?', $query->bindings, $query->sql));// クエリロギングコード }); } }
ここからは、コードの細部の説明です。ロギングを行う関数部はLog::debug(ログに残すメッセージ)です。debugレベルのログを/config/logging.phpの設定に従って出力します。デフォルトでは/storage/logs/laravel.logファイルに追記されます。
ログに残すメッセージはstr_replace_array(‘?’, $query->bindings, $query->sql)です。$query->bindings、$query->sql、str_replace_array(‘?’, $query->bindings, $query->sql)の中身はそれぞれ次の画像の通りです。
それぞれバインドした値、値を入れる前のクエリ、バインドした値を当てはめたクエリです。str_replace_arrayはLaravelのヘルパ関数の一つです。
ヘルパ 5.6 Laravel#str_replace_array()
str_replace_array関数は配列を使い、文字列を指定値へ順番に置き換えます。
str_replace_array('?', $query->bindings, $query->sql)
このコードは値を入れる前のクエリの中の’?’をバインドした値に順番に置き換えるものということです。
このコードの注意点としてログをDBに吐き出す設定にしておくと無限ループが起きることです。ログをDBに保存すると、そのDBへの保存をログする動作が走り、またログのログを……と続きます。