析构函数会在某个对象的所有引用都被删除了(不管是显式销毁还是隐式销毁)或者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) 项目有特殊和明确的要求时,我们可以使用析构函数,显示的销毁对象是,在析构函数中,释放资源.