【问题标题】:Destructor method for static instance variable?静态实例变量的析构函数?
【发布时间】:2015-12-27 22:00:21
【问题描述】:

这是我的课:

class MySQLDB extends PDO{

        private $_connection;
        private static $_instance; //The single instance
        private $_host = MYSQL_SERVER_NAME;
        private $_username = MYSQL_SERVER_USERNAME;
        private $_password = MYSQL_SERVER_PASSWORD;
        private $_database = MYSQL_SERVER_DBNAME;
        /*
        Get an instance of the MySQLDB
        @return Instance
        */
        public static function getInstance() {
                if(!self::$_instance) { // If no instance then make one
                        self::$_instance = new self();
                }
                return self::$_instance;
        }

        // Get PDO MySQL connection
        public function getConnection() {
                return $this->_connection;
        }

    public function __construct(){
        try {
            $this->_connection = new PDO("mysql:host={$this->_host};dbname={$this->_database};charset=utf8", $this->_username, $this->_password);
            $this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->_connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        }
        catch(PDOException $e) {
            throw new Exception($e->getMessage());
        }
    }

    public function __destruct(){
        // unset($this->_connection);
        self::$_instance = null;
    }

}

这是我的主要内容:

$db = MySQLDB::getInstance();

$db->__destruct();

print_r($db).'<br /><br />';

这是输出:

MySQLDB Object ( [_host:MySQLDB:private] => localhost [_username:MySQLDB:private] => username [_password:MySQLDB:private] => [_database:MySQLDB:private] => dbname )

我的问题:为什么我会得到这个输出?如果我像上面那样调用 __destruct() 方法,我不应该只得到一个空输出吗 - 因为我正在清空实例?

或者我应该只在 main 中使用它:

$db = null;
print_r($db).'<br /><br />';

如何确保我已关闭连接并终止了对象?

【问题讨论】:

  • 有两个变量引用您的对象:$MySQLDB::$instance 和 $db。析构函数只取消设置其中之一...

标签: php mysql oop pdo singleton


【解决方案1】:

不,$db-&gt;__destruct() 只是调用__destruct() 方法。它不会神奇地取消设置变量。

析构函数反其道而行之:当对象在没有变量引用它后被垃圾收集器销毁时,然后自动调用析构函数。

你想做的是:

unset($db);

但请注意,不能保证在那个时刻调用析构函数。首先,不能将对象分配给任何其他变量,其次,清理未引用对象的垃圾收集器会定期执行,而不是在每个命令之后执行。

在您的情况下,该对象仍由 MySQLDB::$_instance 引用。如果您将当前取消设置self::$_instance 的__destruct 方法更改为静态方法resetInstance(),您可以使用:

MySQLDB::resetInstance();
unset($db);

然后两个引用都消失了,最终将调用析构函数(同样,如果对象上没有其他引用)。

有关引用计数的更多信息可以在垃圾收集器手册中找到:http://php.net/manual/de/features.gc.refcounting-basics.php

【讨论】:

    猜你喜欢
    • 2021-08-19
    • 1970-01-01
    • 2010-10-16
    • 2012-04-15
    • 2020-07-15
    • 1970-01-01
    • 2011-04-19
    • 2019-03-28
    • 2014-02-03
    相关资源
    最近更新 更多