Laravel listen sql

本文介绍了一个PHP函数,用于在执行SQL语句时进行实时监控,记录执行时间和详细查询内容。通过$ms参数设置阈值,仅记录超过该时间的查询,便于排查性能问题。同时提供了调试模式和信息日志记录选项。
public static function sqlDebug($ms = null, $deBug = false)
    {
        DB::listen(function ($query) use ($ms, $deBug) {
            $tmp = str_replace('?', '"'.'%s'.'"', $query->sql);
            $qBindings = [];
            foreach ($query->bindings as $key => $value) {
                if (is_numeric($key)) {
                    $qBindings[] = $value;
                } else {
                    $tmp = str_replace(':'.$key, '"'.$value.'"', $tmp);
                }
            }
            $tmp = vsprintf($tmp, $qBindings);
            $tmp = str_replace("\\", "", $tmp);
            if ($ms) {
                if ($query->time < $ms) {
                    return;
                }
            }
            //$query->time 是sql语句执行的时间
            $info = 'execution time:'.$query->time.'ms; '.$tmp."\n\n\t";
            if ($deBug) {
                YC_Log::info('[sqlDeBug] [%s]', $info);
            } else {
                var_dump($info);
            }
        });
    }
<think>我们参考了用户提供的多个引用,这些引用主要介绍了在Laravel框架中记录或输出SQL语句的不同方法。用户的问题集中在“如何输出SQL语句”,因此我们需要综合这些方法,给出清晰的步骤和说明。 根据引用内容,我们可以归纳出以下几种方法: 1. 使用Laravel自带的`dd()`或`dump()`方法(引用[2]提到)。 2. 使用事件监听(引用[1]和引用[5]提到,通过监听查询事件并记录)。 3. 使用日志记录(引用[3]提到,将SQL语句打印到日志)。 4. 使用第三方扩展包(如引用[1]提到的`laravelsql`扩展)。 由于用户要求输出SQL语句,我们重点介绍几种常用方法,并给出具体步骤。 ### 方法1:使用`dd()`或`dump()`方法 在查询构造器链式调用末尾使用`dd()`(打印并终止执行)或`dump()`(打印不终止)可以输出SQL语句和绑定参数。 ```php // 使用dd()输出并终止 User::where('id', 1)->dd(); // 使用dump()输出不终止 User::where('id', 1)->dump(); ``` 输出结果会包含完整的SQL语句(已经替换了绑定参数)以及执行时间等信息[^2]。 ### 方法2:监听查询事件 在Laravel中,每次数据库查询都会触发`QueryExecuted`事件。我们可以通过创建一个事件监听器来记录SQL语句。 **步骤:** 1. 创建监听器: ```bash php artisan make:listener QueryListener --event=Illuminate\\Database\\Events\\QueryExecuted ``` 2. 在生成的监听器文件`app/Listeners/QueryListener.php`中编写逻辑: ```php <?php namespace App\Listeners; use Illuminate\Database\Events\QueryExecuted; use Illuminate\Support\Facades\Log; class QueryListener { public function handle(QueryExecuted $event) { // 获取SQL语句和绑定参数 $sql = $event->sql; $bindings = $event->bindings; $time = $event->time; // 将绑定参数替换到SQL语句中 $sql = vsprintf(str_replace('?', "'%s'", $sql), $bindings); // 输出到日志 Log::info("[SQL] {$sql} | Time: {$time}ms"); } } ``` 3. 注册事件监听:在`app/Providers/EventServiceProvider.php`中: ```php protected $listen = [ \Illuminate\Database\Events\QueryExecuted::class => [ \App\Listeners\QueryListener::class, ], ]; ``` 这样,每次执行SQL语句都会记录到日志文件中(默认在`storage/logs`目录下)[^5]。 ### 方法3:使用第三方扩展包 引用[1]提到使用`laravelsql`扩展包。安装后可以方便地输出完整SQL。 1. 安装扩展包: ```bash composer require rap2hpoutre/laravel-log-viewer ``` 注意:这里引用[1]提到的扩展包名称可能是错误的,实际上常用的扩展包是`barryvdh/laravel-debugbar`或`rap2hpoutre/laravel-log-viewer`?但根据引用[1]描述,可能是`laravelsql`,但实际搜索可能没有这个包,所以这里可能需要更正。不过,更常用的是`barryvdh/laravel-debugbar`,它可以显示所有查询。 以`barryvdh/laravel-debugbar`为例: ```bash composer require barryvdh/laravel-debugbar --dev ``` 安装后,在开发环境中会自动在页面底部显示一个调试栏,其中包含执行的SQL语句。 ### 方法4:直接获取查询SQL 对于单个查询,可以直接使用`toSql()`方法获取未替换绑定参数的SQL语句: ```php $query = User::where('id', 1); $sql = $query->toSql(); $bindings = $query->getBindings(); // 手动替换绑定参数 $sql = vsprintf(str_replace('?', "'%s'", $sql), $bindings); echo $sql; ``` ### 总结 根据不同的场景,可以选择不同的方法: - 快速调试单个查询:使用`dd()`或`dump()`。 - 记录所有SQL到日志:使用事件监听。 - 开发阶段实时查看SQL:使用Debugbar扩展包。 以上方法在Laravel框架中都是常用的输出SQL语句的方式[^1][^2][^3][^5]。 §§相关问题§§ 1. Laravel中如何将SQL语句记录到文件而不是页面输出? 2. 如何在Laravel中优化慢查询? 3. 如何配置Laravel的日志系统以按日期分割日志文件? </think>在 Laravel 框架中输出 SQL 语句有以下几种常用方法,结合引用内容为您整理: --- ### 一、直接调试方法(适合快速查看) 1. **使用 `dd()` 或 `dump()`** 在查询构造器后调用内置方法,输出完整 SQL 和结果: ```php // 输出 SQL 并终止执行(dd = dump and die) User::where('id', 1)->dd(); // 输出 SQL 不终止执行 User::where('id', 1)->dump(); ``` **效果**:直接显示绑定了参数的完整 SQL(如 `SELECT * FROM users WHERE id = 1`)[^2]。 2. **使用 `toSql()` 获取未绑定参数的 SQL** ```php $sql = User::where('id', 1)->toSql(); dd($sql); // 输出:select * from `users` where `id` = ? ``` > ✅ 需手动替换参数占位符 `?`[^3]。 --- ### 二、全局记录 SQL(适合长期调试) 1. **通过事件监听记录到日志** **步骤**: ```php // 步骤1: 创建监听器 php artisan make:listener QueryListener --event=QueryExecuted // 步骤2: 在 app/Listeners/QueryListener.php 中编写逻辑 public function handle(QueryExecuted $event) { $sql = vsprintf( str_replace('?', "'%s'", $event->sql), $event->bindings ); Log::channel('sql')->debug("SQL: {$sql} | Time: {$event->time}ms"); } // 步骤3: 在 app/Providers/EventServiceProvider.php 注册事件 protected $listen = [ 'Illuminate\Database\Events\QueryExecuted' => [ 'App\Listeners\QueryListener' ] ]; ``` **效果**:所有 SQL 会记录到 `storage/logs/sql.log`[^1][^5]。 2. **简化版中间件记录** 在 `App\Http\Middleware` 中创建中间件: ```php public function handle($request, Closure $next) { DB::listen(function ($query) { Log::debug("SQL: " . $query->sql, $query->bindings); }); return $next($request); } ``` --- ### 三、使用扩展包(推荐) 安装 **Laravel Debugbar** 或 **Laravel SQL Monitor**: ```bash composer require barryvdh/laravel-debugbar --dev ``` **效果**:页面底部自动显示所有执行的 SQL、耗时及调用位置[^1]。 --- ### 四、复杂场景处理 ```php // 示例:复杂查询输出(引用[4]) $query = DB::table('a') ->leftJoin('b', 'a.x', '=', 'b.y') ->where('col', 0) ->where('col1', 1) ->where(function ($q) { $q->where('col2', 2)->orWhere('col3', 3); }) ->dd(); // 直接输出完整 SQL ``` --- ### 💡 关键区别总结 | **方法** | 适用场景 | 是否显示参数 | 是否记录时间 | |-------------------|----------------|-------------|------------| | `dd()`/`dump()` | 单次调试 | ✅ 是 | ✅ 是 | | 事件监听日志 | 全局监控 | ✅ 是 | ✅ 是 | | `toSql()` | 获取原始 SQL 结构| ❌ 否 | ❌ 否 | | Debugbar 扩展 | 开发环境集成 | ✅ 是 | ✅ 是 | > 建议:开发调试用 Debugbar 扩展,生产环境排查用事件监听日志[^1][^3][^5]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值