美文网首页
记录运行时 SQL 语句(针对 5.2 版本)

记录运行时 SQL 语句(针对 5.2 版本)

作者: 7c03aed0f01f | 来源:发表于2016-11-30 10:27 被阅读44次

    记录运行时 SQL 语句(针对 5.2 版本)

    在开发过程中,我们有时候可能希望记录下程序执行的每一条 SQL,在 Laravel 中我们可以利用事件及其监听器很方便的实现这一需求。

    本站之前曾发布过一篇相关的文章,不过是针对 5.1 及更老的版本,而在 Laravel5.2 中不再适用。所以就有了此文。

    第一步:创建监听器

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

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

    第二步:注册事件

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

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

    当然在类前面你需要 use App\Listeners\QueryListener; 不然就报类不存在了。

    第三步:添加逻辑

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

    <?php
    
    namespace App\Listeners;
    
    use Illuminate\Database\Events\QueryExecuted;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Log;
    
    class QueryListener
    {
        /**
         * Create the event listener.
         *
         * @return void
         */
        public function __construct()
        {
            //
        }
    
        /**
         * Handle the event.
         *
         * @param  QueryExecuted  $event
         * @return void
         */
        public function handle(QueryExecuted $event)
        {
            if (env('APP_ENV', 'production') == 'local') {
                $sql = str_replace("?", "'%s'", $event->sql);
    
                $log = vsprintf($sql, $event->bindings);
    
                Log::info($log);
            }
        }
    }
    
    

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

    至此大功告成,在调试模式下程序所执行的 SQL 都会被一一记录在案,方便我们调试。形式如下:

    [2016-07-29 18:08:15] local.INFO: select * from `app_articles` where `app_articles`.`id` = '40' limit 1
    

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

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

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

    相关文章

      网友评论

          本文标题:记录运行时 SQL 语句(针对 5.2 版本)

          本文链接:https://www.haomeiwen.com/subject/ibazpttx.html