Laravel SQLの実行クエリログを出力する
LaravelではEloquentやQueryBuilderを介してデータベースとやり取りしますが、実際に実行されるSQLを確認する時に使用する方法を3つご紹介します。
環境
- PHP 8.0
- MySQL 8.0.17
- Laravel 8.23.1
1. QueryBuilderをSQLに変換したい時
クエリビルダには、 toSql()
メソッドを呼び出すことでSQL文を取得できます。プレースホルダの値は getBindings()
で取得できます。
$query = \App\User::where('id', 1);
dd($query->toSql(), $query->getBindings());
tinkerで確認する時にも便利です。
2. 複数のQueryBuilderのSQLを確認したい時
SQL実行前に DB::enableQueryLog()
でクエリログを有効化し、SQL実行後に DB::getQueryLog()
メソッドを利用することで、そのクエリの内容や、実行時間を取得できます。
\DB::enableQueryLog();
\App\User::all();
dd(\DB::getQueryLog());
有効化した後のクエリログを取得できます。
3. サービスプロバイダーに登録してログファイルに自動出力
- 環境変数でログ出力の有効/無効を切り替えする
DataBaseQueryServiceProvider を作成
$ php artisan make:provider DataBaseQueryServiceProvider
app/Providers/DataBaseQueryServiceProvider.php
ファイルが生成される。
config/app.php へ追記
'providers' => [
// ... 省略
App\Providers\DataBaseQueryServiceProvider::class,
],
providers
の配列に作成した DataBaseQueryServiceProvider
を登録します。
app/Providers/DataBaseQueryServiceProvider.php を編集
<?php declare(strict_types=1);
namespace App\Providers;
use Carbon\Carbon;
use DateTime;
use Illuminate\Database\Events\TransactionBeginning;
use Illuminate\Database\Events\TransactionCommitted;
use Illuminate\Database\Events\TransactionRolledBack;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
class DataBaseQueryServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
if (config('logging.sql.enable') === false) {
return;
}
DB::listen(function ($query): void {
$sql = $query->sql;
foreach ($query->bindings as $binding) {
if (is_string($binding)) {
$binding = "'{$binding}'";
} elseif (is_bool($binding)) {
$binding = $binding ? '1' : '0';
} elseif (is_int($binding)) {
$binding = (string) $binding;
} elseif ($binding === null) {
$binding = 'NULL';
} elseif ($binding instanceof Carbon) {
$binding = "'{$binding->toDateTimeString()}'";
} elseif ($binding instanceof DateTime) {
$binding = "'{$binding->format('Y-m-d H:i:s')}'";
}
$sql = preg_replace('/\\?/', $binding, $sql, 1);
}
Log::debug('SQL', ['sql' => $sql, 'time' => "{$query->time} ms"]);
});
Event::listen(TransactionBeginning::class, function (TransactionBeginning $event): void {
Log::debug('START TRANSACTION');
});
Event::listen(TransactionCommitted::class, function (TransactionCommitted $event): void {
Log::debug('COMMIT');
});
Event::listen(TransactionRolledBack::class, function (TransactionRolledBack $event): void {
Log::debug('ROLLBACK');
});
}
}
config/logging.php を編集
return [
/*
|--------------------------------------------------------------------------
| Custom Log
|--------------------------------------------------------------------------
*/
'sql' => [
'enable' => env('LOG_SQL_ENABLE', false),
],
];
.env を編集
LOG_SQL_ENABLE=true
※本番環境ではパフォーマンスやセキュリティ上の問題から無効化した方が良いです!
お試し実行
routes/web.php
<?php
use App\User;
Route::get('/', function () {
$user = DB::transaction(function () {
$user = factory(User::class)->create();
$user->name = 'change name';
$user->save();
$user->delete();
return factory(User::class)->create();
});
User::find($user->id);
return view('welcome');
});
適当にSQLを発行しそうな処理を加えて、いつものウェルカムページを表示する。
storage/logs/laravel-***.log
ログファイルを確認すると次のようなデータベースクエリログが出力されていればok
[2019-06-15 07:14:09] local.DEBUG: START TRANSACTION
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"insert into `users` (`name`, `email`, `email_verified_at`, `password`, `remember_token`, `updated_at`, `created_at`) values ('Pietro Conn', '[email protected]', '2019-06-15 07:14:09', 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'rch9DXbn5W', '2019-06-15 07:14:09', '2019-06-15 07:14:09')","time":"2.19 ms"}
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"update `users` set `name` = 'change name', `users`.`updated_at` = '2019-06-15 07:14:09' where `id` = 23","time":"1.66 ms"}
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"delete from `users` where `id` = 23","time":"1.33 ms"}
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"insert into `users` (`name`, `email`, `email_verified_at`, `password`, `remember_token`, `updated_at`, `created_at`) values ('Zoila Wintheiser', '[email protected]', '2019-06-15 07:14:09', 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'Ya6yCp6UTX', '2019-06-15 07:14:09', '2019-06-15 07:14:09')","time":"1.61 ms"}
[2019-06-15 07:14:09] local.DEBUG: COMMIT
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"select * from `users` where `users`.`id` = 24 limit 1","time":"4.41 ms"}
関連記事
Author And Source
この問題について(Laravel SQLの実行クエリログを出力する), 我々は、より多くの情報をここで見つけました https://qiita.com/ucan-lab/items/753cb9d3e4ceeb245341著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .