如何实现thinkphp中Db类的方法调用风格?

2020-05-25 科技 73阅读

我们先来看下官网对listen的说明:如果开启数据库的调试模式的话,你可以对数据库执行的任何SQL操作进行监听。这无疑很方便我们进行增删改查的调试,以及通过执行的时间进行有效的sql优化,

友情提示:数据库监听要写在执行sql语句的前面,因为只有在调用Db::listen之后的SQL语句才会被监听,调用之前的语句不会被监听。至于为什么我们后面讲!

使用如下方法:

123456

Db::listen(function($sql, $time, $explain){    // 记录SQL    echo $sql. ' ['.$time.'s]';    // 查看性能分析结果    dump($explain);});

有很多小伙伴疑问该方法应该放在哪里?使用之后为什么没有效果,很可能就是提示上所说的那样了,那么接下来我们简单分析一下这个方法!

1、从Db::listen(),可以看出listen是Db中的一个静态方法,那么我们就去找db类

2、从Db类中没有找到该方法,但是我们从use think\db\Connection可以看出,引入了Connection类,我们在这个类找一下这个方法!

12345678910

public function listen($callback){    self::$event[] = $callback;}

3、event 保存我们传入的回调方法

4、在看下面这2个方法

12345678910111213141516171819202122232425262728293031323334353637383940414243444546

protected function debug($start, $sql = ''){    if (!empty($this->config['debug'])) {        // 开启数据库调试模式        if ($start) {            Debug::remark('queryStartTime', 'time');        } else {            // 记录操作结束时间            Debug::remark('queryEndTime', 'time');            $runtime = Debug::getRangeTime('queryStartTime', 'queryEndTime');            $sql     = $sql ?: $this->getLastsql();            $log     = $sql . ' [ RunTime:' . $runtime . 's ]';            $result  = [];            // SQL性能分析            if ($this->config['sql_explain'] && 0 === stripos(trim($sql), 'select')) {                $result = $this->getExplain($sql);            }            // SQL监听            $this->trigger($sql, $runtime, $result);        }    }} protected function trigger($sql, $runtime, $explain = []){    if (!empty(self::$event)) {        foreach (self::$event as $callback) {            if (is_callable($callback)) {                call_user_func_array($callback, [$sql, $runtime, $explain]);            }        }    } else {        // 未注册监听则记录到日志中        Log::record('[ SQL ] ' . $sql . ' [ RunTime:' . $runtime . 's ]', 'sql');        if (!empty($explain)) {            Log::record('[ EXPLAIN : ' . var_export($explain, true) . ' ]', 'sql');        }    }}

5、当我们执行了sql语句,就会触发会调用debug方法将执行日志写入日志文件中,同事调用trigger方法,如果我们最开始已经传入了回调方法,也就是

1

self::$event

不为空,(说明我们在执行sql语句之前就已经设置了监听)我们将调用我们的回调函数!

1

call_user_func_array

总结:在执行sql语句之前我们需要先设置监听,这就是为什么要把Db::listen()写在执行sql语句的前面!

下面我们来看下实际的效果:

1234567891011121314

public function expo(){    Db::listen(function($sql, $time, $explain){        // 记录SQL        echo $sql. ' ['.$time.'s]';        // 查看性能分析结果        dump($explain);    });    //Get data based on columns,执行sql语句    foreach($channel as $v)        $list[$v['id']] =  GetData::getData('news',"channel_id = {$v['id']} and status = 2",'id,title,author,create_time,channel_id,file_path','order_by desc','0,5');    return view('expo',[        'list' => $list    ]);}

效果图:

声明:你问我答网所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系fangmu6661024@163.com