laravel 查看sql
方法一:
我们有时候想测试一段代码生产的 SQL 语句,比如: 我们想看 App\User::all();
产生的 SQL 语句,我们简单在 routes.php 做个实验即可:
//app/Http/routes.php
Route::get('/test-sql', function() {
DB::enableQueryLog();
$user = App\User::all();
return response()->json(DB::getQueryLog());
});
然后我们在浏览器打开 http://www.yousite.com/test-sql
即可看到 $user = User::all();
所产生的 SQL 了。
[
{
query: "select * from `users` where `users`.`deleted_at` is null",
bindings: [ ],
time: 1.37
}
]
方法二:
在routes.php添加如下代码
Event::listen('illuminate.query', function($sql, $param) {
file_put_contents(public_path().'/sql.log',$sql.'['.print_r($param, 1).']'."\r\n",8);
//echo $sql . ", with[" . join(',', $param) ."]</br>";
});
方法三:
调用vendor\laravel\framework\src\Illuminate\Database\Query的toSql方法:
$query->toSql();
方法四:
使用监听器
第一步:创建监听器
php artisan make:listener QueryListener --event=illuminate.query
生成文件于 app/Listeners/QueryListener.php
然后删除 app/Listeners/QueryListener.php
顶部的 use App\Events\illuminate.query;
, 这是自动生成的。
第二步:注册事件
打开 app/Providers/EventServiceProvider.php
,在 $listen
中添加 illuminate.query
事件的监听器为 QueryListener
:
protected $listen = [
'illuminate.query' => [
QueryListener::class,
],
];
当然在类前面你需要 use App\Listeners\QueryListener;
不然就报类不存在了。
第三步:添加逻辑
修改上面生成的文件,我们把 SQL 查询记录到日志里,所以编辑 handle
方法为:
/**
* Handle the event.
*
* @param Events $event
* @return void
*/
public function handle($sql, $params)
{
if (env('APP_ENV', 'production') == 'local') {
foreach ($params as $index => $param) {
if ($param instanceof DateTime) {
$params[$index] = $param->format('Y-m-d H:i:s');
}
}
$sql = str_replace("?", "'%s'", $sql);
array_unshift($params, $sql);
Log::info(call_user_func_array('sprintf', $params));
}
}
上面我们用到了两个类:Log
与 DateTime
, 别忘记引入它们。
解释一下上面的代码:
illuminate.query
事件触发时的参数为两个:handle($sql, $params)
, SQL 预处理语句与查询参数值;- 我们只在开发环境记录 SQL:
env('APP_ENV', 'production') == 'local'
; - 我们的参数里可能存在日期类型,所以直接记日志会报错,所以处理一下:
$param instanceof DateTime
;
然后跑一下试试吧,应该在日志里就能看到:
[2015-07-10 02:45:39] local.INFO: update `tricks` set `view_cache` = "10", `updated_at` = "2015-07-10 02:45:39" where `id` = "2"