析构函数会在某个对象的所有引用都被删除了(不管是显式销毁还是隐式销毁)或者php文件执行时执行。
某个对象的所有引用被删除:
1、使用unset(对象名),将对象名销毁2、$对象名 = null3、$对象名 = 'abc'
显式销毁:
上面写的三种方式,都是显式销毁,所谓显式销毁就是程序员主动删除对象引用。
如果程序员不去显式销毁对象,那么在程序执行完毕后,这个对象就会被系统销毁,这个就是系统销毁。也叫隐式销毁。
基本语法:
class 类名{
public function __destruct(){
//函数体
//析构函数的重要作用,就是释放对象创建的资源
//比如 数据库连接,文件句柄,绘图句柄。。。
}
}
说明:
(1)析构函数都是public
(2)__destruct是关键字,不要修改
(3)析构函数没有形参
(4)析构函数时系统调用的
(5)析构函数在如下情况会被系统调用
1、php文件执行完
2、在某个对象的所有引用都被删除或者当对象被显式销毁时执行。
<?php
header('content-type:text/html;charset=utf-8');
class xghs{
public $name;
public function __construct($name){
$this->name = $name;
}
public function __destruct(){
echo '<br> 析构函数被调用'.$this->name;
}
}
$p1 = new xghs('大和尚');
$p2 = new xghs('小和尚');
echo '<br>-------<br>';
?>
unset对象:
<?php
class Cat{
public $name;
public function __construct($name){
$this->name = $name;
}
public function __destruct($name){
echo '<br>析构函数'.$this->name;
}
}
$cat1 = new Cat('小猫');
$cat2 = &$cat2;
//下面的代码只是把$cat1销毁,而不是把$cat1指向的变量销毁,此时对象$cat1的对象标识符还在,由$cat2指向
unset($cat1);
//下面的代码是把$cat2指向的变量赋值为空,而不是销毁$cat2,此时$cat1的对象标识符就变成空了
$cat2 = null;
?>
需要注意的栗子(unset或者null等等调用或者不调用析构函数都只是清空了对象标识符,而对象还存在内存中,只有在析构函数中手动销毁那些资源才会在内存中完全消失):
<?php
header('content-type:text/html;charset=utf8');
class DAOMySQL{
public $mysql_link;
public function __construct($host,$name,$password){
$this->mysql_link = @mysql_connect($host,$name,$password);
}
public function __destruct(){
echo '<br>析构函数被调用...';
//因为$dao = null并没有销毁对象的资源(或者说对象),而只销毁了对象描述符,可以用下面的方法销毁对象资源
//mysql_close($this->mysql_link);
}
}
$dao = new DAOMySQL('localhost','root','root');
var_dump($dao->mysql_link);
mysql_select_db('php07');
$sql = 'select * from `php07_student`';
$res = mysql_query($sql,$dao->mysql_link);
while($row = mysql_fetch_assoc($res)){
echo '<pre>';
var_dump($row);
}
echo '000000000000';
$dao = null;
echo '<br>111111111111';
//还是把上面的内容查出来了,说明只是销毁了对象,而没有销毁对象资源,下面的连接还是可以自动在内存中找到上面的连接资源
mysql_select_db('php07');
$sql = 'select * from `php07_student`';
$res = mysql_query($sql);
while($row = mysql_fetch_assoc($res)){
echo '<pre>';
var_dump($row);
}
?>
说明:
(1) 关于在析构函数中释放资源的问题,如果我们对效率没有很高很特殊的要求,完全可以不使用析构函数.
(2) 如果我们不确定代码后面是否还会使用资源(比如链接),那么我们建议最好不要使用析构函数.
(3) 项目有特殊和明确的要求时,我们可以使用析构函数,显示的销毁对象是,在析构函数中,释放资源.