【发布时间】:2017-09-03 10:15:13
【问题描述】:
我最近一直在重新设计一个古老的 PHP 应用程序,它的大部分代码都包含在每个页面的 1000 多行 PHP 文件中。我首先将大部分代码重构为类。我最近一直在研究数据库连接,并开始为它编写一个类。我决定将$mysqli->close() 扔到析构函数中(我正在使用OO 方法)。
不幸的是,我几乎立即就遇到了问题。当页面完成渲染时(或者当没有更多对 DB 对象的引用时)而不是关闭 MySQLi 连接,它只是立即关闭。我通过编写一个简单的测试对此进行了测试:
$db = new DBConnect(); //My abstraction class
$db->getSQL()->query("SELECT 1"); //Query fails. Error message states connection closed.
我的析构函数如下所示:
public function __destruct() {
$this->mysqli->close();
}
我的构造函数如下所示:
public function __construct() {
$this->mysqli=new mysqli(\MainConfig::$database['host'], \MainConfig::$database['user'], \MainConfig::$database['pass'], \MainConfig::$database['db']);
if($this->mysqli->connect_error) {
die('Connect error (' . $this->mysqli->connect_errno . ') ' . $this->mysqli->connect_error); //This is not ever fired.
}
}
我知道这不是关闭连接的其他代码,因为如果我注释掉 $this->mysqli->close() 行,那么代码会按预期工作。在我看来,析构函数 立即 触发,这不是所需的行为。我是否误解了它们的工作原理?
【问题讨论】:
-
看起来有一些代码丢失导致了这种情况。 PHP 垃圾收集器不会破坏对象,除非不再引用它。
-
每个
DBConnect实例是否有自己的mysqli 连接对象,或者您是否缓存它们并在不同对象之间共享它们? -
@b.enoit.be 项目中的所有源文件都复制了这种行为,包括那里的测试代码。我无法发布 1000 行长的源文件!
-
也发布构造函数。
-
恕我直言,通常没有必要明确关闭 mysqli 连接。如果 $db 是一个全局变量,它直到脚本结束才会消失,并且连接会自动关闭。