简体   繁体   中英

Destructor method for static instance variable?

This is my class:

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;
    }

}

This is in my main:

$db = MySQLDB::getInstance();

$db->__destruct();

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

This is the output:

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

My question: Why do I get this output? If I'm calling the __destruct() method like above, shouldn't I get just an empty output - since I'm nulling the instance?

Or maybe I should just use this in main:

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

How do I make sure I've closed the connection and killed the object?

No, $db->__destruct() does nothing more than calling the __destruct() method. It does not magically unset the variable.

Destructors work the other way around: When the object gets destroyed by the garbage collector after no variable references it anymore, then the destructor is called automatically.

What you want to do is:

unset($db);

But note that the destructor is not guaranteed to be called in that very moment. First, the object must not be assigned to any other variable and second, the garbage collector that cleans up unreferenced objects is executed periodically and not after each command.

In your case, the object is still referenced by MySQLDB::$_instance . If you change your current __destruct method which unsets self::$_instance to a static method resetInstance() , you can use:

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

then both references are gone and the desctructor will be called eventually (again, if there are no other references on the object).

More information on the topic of reference counting can be found in the garbage collector manual: http://php.net/manual/de/features.gc.refcounting-basics.php

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM