laravel默认不记录sql查询,需调用db::enablequerylog()启用(仅debug模式下推荐),日志存于内存,用db::getquerylog()获取;生产环境应监听queryexecuted事件并安全记录。

开启 Laravel 查询日志功能
默认情况下,Laravel 不记录 SQL 查询,必须手动启用。调用 DB::enableQueryLog() 是最直接的方式,但它只对当前请求生命周期生效,且仅在 debug 模式下(APP_DEBUG=true)才建议使用——否则可能因日志体积过大拖慢响应。
- 必须在执行查询前调用,例如在控制器方法开头或中间件中
- 对队列任务、命令行 Artisan 命令同样有效,但需注意:命令默认不加载完整 HTTP 环境,
APP_DEBUG需显式配置 - 启用后所有通过
DB::、Eloquent、查询构造器发出的语句都会被记录,包括隐式触发的关联加载(如$user->posts)
获取并查看已记录的 SQL 日志
日志不是自动打印或写入文件,而是保存在内存中,需主动调用 DB::getQueryLog() 提取。返回的是一个数组,每个元素包含 query、bindings、time 三项关键字段。
-
query是带问号占位符的原始 SQL,不是最终执行的字符串 -
bindings是参数值数组,需手动替换才能看到真实语句(Laravel 不自动拼接,避免 SQL 注入风险) -
time单位是毫秒,可用于快速识别慢查询 - 常见误操作:在
enableQueryLog()前就调用getQueryLog(),结果为空数组
在生产环境安全地记录 SQL(不依赖 QueryLog)
生产环境禁用 DB::enableQueryLog(),应改用 Laravel 的底层事件机制 + 自定义日志通道。核心是监听 Illuminate\Database\Events\QueryExecuted 事件。
- 在
EventServiceProvider的$listen中添加:Illuminate\Database\Events\QueryExecuted::class => [App\Listeners\LogQueryListener::class] -
LogQueryListener中可访问$event->sql、$event->bindings、$event->connectionName和$event->time - 务必过滤敏感操作(如
password、token字段出现在sql中时跳过记录) - 避免在监听器里做耗时操作(如写磁盘、发 HTTP 请求),推荐推送到队列或使用异步日志驱动(如 Monolog 的
RotatingFileHandler)
调试时快速输出带参数的可执行 SQL
开发中常需要看到“真正执行了什么”,而不是带问号的模板。可以用辅助函数手动替换 bindings,但要注意类型转换和引号包裹规则。
function dumpSql($query, $bindings) {
$search = array_map(function ($b) { return is_string($b) ? "'".addslashes($b)."'" : $b; }, $bindings);
return str_replace(['?', '%'], $search, $query);
}
// 使用示例:echo dumpSql($log['query'], $log['bindings']);
- 该函数不处理
NULL、布尔值、数组绑定等复杂情况,仅适用于简单调试 - Eloquent 的
toSql()方法(如User::where('id', 1)->toSql())只生成 SQL 模板,不包含实际参数,也不触发查询 - 不要在生产代码中保留这类调试函数,容易泄露敏感数据
getQueryLog() 并 var_dump,会卡住整个响应周期。











