laravel 各版本- 原生SQL打印之SQL监听 –方法

原生sql打印有三种,分别是使用debugbar插件、使用局部SQL打印方法、使用事件监听器全局设置SQL原生态打印,本次讲的是第三种,事件监听打印原生Sql,每个laravel版本不太一样,如下:

 

Laravel LTS 5.1版本

1.创建sql监听器

php artisan make:listener QueryListener --event=illuminate.query 

生成文件于 app/Listeners/QueryListener.php

然后删除 app/Listeners/QueryListener.php 顶部的 use App\Events\illuminate.query;, 这是自动生成的。

二、注册SQL监听事件

打开 app/Providers/EventServiceProvider.php,在 $listen 中添加 illuminate.query 事件的监听器为 QueryListener

头部引入 use App\Listeners\QueryListener;

protected $listen = [  
        'illuminate.query' => [
            QueryListener::class,
        ],
    ];

三、编写SQL打印逻辑代码

编辑app/Listeners/QueryListener.php文件

/**
     * 日志打印方法.
     *
     * @param  illuminate.query  $event
     * @return void
     */
    public function handle($sql, $params)
    {
        // dd($sql);
        // dd($params);
        // 如果env中属于本地开发则进入该判断
        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);
            // dd($params);
            \Log::info('SQL语句输出------------>'.call_user_func_array('sprintf', $params));
        }
    }

接着在控制器中输入测试代码来测试下:

public function test() { 
$users = \DB::table('users')->where('id','<','10')->get();
dd($users);
 }

从浏览器器访问可显示出打印的用户信息,再在后台 /storage/logs/laravel.log日志中可看到原生的sql语句。

 

Laravel LTS 5.2版本之后(至少到5.5是可以)

一、创建监听器

php artisan make:listener QueryListener --event=Illuminate\Database\Events\QueryExecuted  

生成文件于 app/Listeners/QueryListener.php

二、注册事件

打开 app/Providers/EventServiceProvider.php,在 $listen 中添加 Illuminate\Database\Events\QueryExecuted 事件的监听器为 QueryListener

命名空间中 use App\Listeners\QueryListener;

protected $listen = [  
        'Illuminate\Database\Events\QueryExecuted' => [
            'App\Listeners\QueryListener',
        ],
    ];

三、添加逻辑

光有一个空的监听器是不够的,我们需要自己实现如何把 $sql 记录到日志中。为此,对 QueryListener 进行改造,完善其 handle 方法如下:

/**
     * 日志打印方法.
     *
     * @param  illuminate.query  $event
     * @return void
     */
    public function handle(QueryExecuted $event)
    { 
if (env('APP_ENV', 'production') == 'local') {
$sql = str_replace("?", "'%s'", $event->sql); //$event->sql是获取参数值为?的sql语句 
$log = vsprintf($sql, $event->bindings); //$event->bindings是获取到绑定的参数数组 
//与 sprintf() 不同,vsprintf() 中的参数位于数组中,数组元素将被插入到主字符串中的百分号(%)符号处。
Log::info($log); 
} 
    } 

上面我们用到了 Log 门面,请注意在类开头引用,或者使用 \Log::info() 代替之。

可以看到,相对于 5.1 中的做法,本文中所诉的有不少变化。

首先,5.2 中不再有 illuminate.query 等形式的框架事件标识,所以我们在注册事件及其监听器时需要使用真实的事件类名。

其次,5.2 中事件监听器的 handle 方法只支持接收一个参数,此例中是一个\ Illuminate\Database\Events\QueryExecuted 类型的对象,该对象中包含查询时的 SQL、查询参数及查询时间等量,对于我们记录日志而言十分方便。

如此打印原生SQL就成功了, 对我们测试定会有大大大帮助。

原文转载链接:https://www.blog8090.com/laravel-lts-yuan-sheng-sqlda-yin-zhi-sqljian-ting-fang-fa-er/

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注