私はphpデストラクタについて本当に奇妙なことを見つけました:
基本的に、ファクトリを使用してアダプターをロードし、ロードするアダプター (mysql、mysqli など) を定義するデータベース管理クラスがあります。
クラス自体はかなり長くなりますが、コードは現在の問題に関与していないため、コードの興味深い部分だけを書き留めます。
この問題は mysql でのみ発生します (mysqli と pdo は問題なく動作します) が、互換性のために、mysql を取り除くことは問題外です。
class manager
{
private static $_instance;
public static function getInstance()
{
return isset(self::$_instance) ? self::$_instance : self::$_instance = new self;
}
public function getStandaloneAdapter()
{
return new mysql_adapter(array('host'=>'127.0.0.1', 'username' => 'root', 'password' => '', 'dbname' => 'etab_21'));
}
}
abstract class abstract_adapter
{
protected $_params;
protected $_connection;
public function __construct($params)
{
$this->_params = (object)$params;
}
public function __destruct()
{
echo 'destructor<br/>';
var_dump(debug_backtrace(false));
$this->closeConnection();
}
abstract public function closeConnection();
}
class mysql_adapter extends abstract_adapter
{
public function getConnection()
{
$this->_connect();
if ($this->_connection) {
// switch database
$this->_useDB($this->_params->dbname);
}
return $this->_connection;
}
protected function _connect()
{
if ($this->_connection) {
return;
}
// connect
$this->_connection = mysql_connect(
$this->_params->host,
$this->_params->username,
$this->_params->password,
true
);
if (false === $this->_connection || mysql_errno($this->_connection)) {
$this->closeConnection();
throw new Mv_Core_Db_Exception(null, Mv_Core_Db_Exception::CONNECT, mysql_error());
}
if ($this->_params->dbname) {
$this->_useDB($this->_params->dbname);
}
}
private function _useDB($dbname)
{
return mysql_select_db($dbname, $this->_connection);
}
public function isConnected()
{
$isConnected = false;
if (is_resource($this->_connection)) {
$isConnected = mysql_ping($this->_connection);
}
return $isConnected;
}
public function closeConnection()
{
if ($this->isConnected()) {
mysql_close($this->_connection);
}
$this->_connection = null;
}
}
だからここに私が実行しているテストがあります:
$sadb1 = manager::getInstance()->getStandaloneAdapter()->getConnection();
var_dump($sadb1);
そして私が得ている出力:
destructor
array
0 =>
array
'file' => string '**\index.php' (length=48)
'line' => int 119
'function' => string '__destruct' (length=10)
'class' => string 'abstract_adapter' (length=16)
'type' => string '->' (length=2)
'args' =>
array
empty
1 =>
array
'file' => string '**\index.php' (length=48)
'line' => int 119
'function' => string 'unknown' (length=7)
resource(26, Unknown)
テストをこれに変更すると:
$sadb1 = manager::getInstance()->getStandaloneAdapter();
var_dump($sadb1->getConnection());
出力は良好です:
resource(26, mysql link)
destructor
array
0 =>
array
'function' => string '__destruct' (length=10)
'class' => string 'abstract_adapter' (length=16)
'type' => string '->' (length=2)
'args' =>
array
empty
えっ?!