总有人间一两风,填我十万八千梦

ThinkPHP3.2 关闭/断开数据库连接

PHP Zero、J 1516℃ 0评论

不要问我为嘛还在用ThinkPHP 3.2.3 ~~因为稳定就行(不敢升级TP5、变化太大怕有问题)

因为项目中需要做一个后台的长时间的操作任务,因此需要在执行任务之前彻底断开与数据库的连接~~ 也就是能够在MySQL Workbench中的Status页面中看到Connections减少!

百度了一番,看到有人使用了下面的方法 (在Common|Api模式下,位于ThinkPHP\Library\Think\Model.class.php文件中的 db( $linkNum='',$config='',$force=false )函数

$Model-> db(0,null) ;

db函数的代码如下所示

/**
     * 切换当前的数据库连接
     * @access public
     * @param integer $linkNum  连接序号
     * @param mixed $config  数据库连接信息
     * @param boolean $force 强制重新连接
     * @return Model
     */
    public function db($linkNum='',$config='',$force=false) {
        if('' === $linkNum && $this->db) {
            return $this->db;
        }

        if(!isset($this->_db[$linkNum]) || $force ) {
            // 创建一个新的实例
            if(!empty($config) && is_string($config) && false === strpos($config,'/')) { // 支持读取配置参数
                $config  =  C($config);
            }
            $this->_db[$linkNum]            =    Db::getInstance($config);
        }elseif(NULL === $config){
            $this->_db[$linkNum]->close(); // 关闭数据库连接
            unset($this->_db[$linkNum]);
            return ;
        }

        // 切换数据库连接
        $this->db   =    $this->_db[$linkNum];
        $this->_after_db();
        // 字段检测
        if(!empty($this->name) && $this->autoCheckFields)    $this->_checkTableInfo();
        return $this;
    }

这个db函数主要用于切换当前数据库的连接,当第2个参数$config 为 null 的时候,将会调用 close方法(第21行),这个close方法对应的是ThinkPHP\Library\Think\Db\Driver.class.php中的close方法,对应的原始代码如下

/**
     * 关闭数据库
     * @access public
     */
    public function close() {
        $this->_linkID = null;
    }

上述代码中,只是简单的将当前使用的PDO对象赋值为null。对于PDO方式连接数据库而言,只需要将对应的PDO对象赋值为null 释放即可断开连接。

但是!!!根据官方的文档说明,只要当所有的 PDO 引用全部释放之后才会断开连接。这里将_linkID 直接赋值为null,并没有实现释放所有的PDO引用,经过查看源代码之后发现,在Driver.class.php中还有一个$this->linkID的数组,这个数组会根据连接序号(作为索引)来保存对应的PDO对象,因此这个数组中也引用了PDO对象,此外还有一个PDOStatement对象也需要释放。

修改一下close方法:

/**
     * 关闭数据库 ,释放 linkID数组中的PDO引用、_linkID PDO引用以及PDOStatement引用
     * @access public
     */
    public function close() {
        // 删除 数组中的 PDO引用
        foreach($this->linkID as $k => &$pdo){
            if($pdo === $this->_linkID){
                $this->linkID[$k] = null;
                break;
            }
        }
        //删除当前 引用的 PDO
        $this->_linkID = null;
        // 删除 PDOStatement 不然 不会关闭
        $this->free();
    }

然后再次使用 $Model->db( [序号] ,null);就可以释放对应的数据库连接了。

转载请注明:悠然品鉴 » ThinkPHP3.2 关闭/断开数据库连接

喜欢 (1)or分享 (0)
发表我的评论
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(2)个小伙伴在吐槽
  1. 有用 感谢大佬
    12021-11-22 17:42 回复
  2. 支持一下。。。
    亚马逊fba2021-08-12 09:58 回复