laravel框架打印出完整的SQL语句

将下面代码放在AppServiceProvider中的boot方法中:

DB::listen(
            function ($sql) {
                foreach ($sql->bindings as $i => $binding) {
                    if ($binding instanceof \DateTime) {
                        $sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
                    } else {
                        if (is_string($binding)) {
                            $sql->bindings[$i] = "'$binding'";
                        }
                    }
                }

                // Insert bindings into query
                $query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);

                $query = vsprintf($query, $sql->bindings);

                // Save the query to file
                $logFile = fopen(
                    storage_path('logs' . DIRECTORY_SEPARATOR . 'laravel-' . date('Y-m-d') . '-sql.log'),
                    'a+'
                );
                fwrite($logFile, date('Y-m-d H:i:s') . ': ' . $query . PHP_EOL);
                fclose($logFile);
            }
        );


日志在storage/log/laravel-xxx-sql.log

<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]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值