随着面向对象编程的广泛展开,面向对象展示了其中不少有趣的问题。相信不少初学者学习php面向对象时会接触两个函数,构造函数与析构函数。构造函数彷佛用的更多,析构函数用的较少(相对初学者有限编程经验而言,笔者也是如此。)在功能上,构造函数在建立对象时调用,析构函数在对象销毁时调用,都无需特地去调用,一头一尾,倒也是先后照应。php
析构函数经常处理的事务是一些资源释放的工做,好比前面有fopen(),这里调用fclose(),前面有imagecreatefromjepg(),这里调用imagedestory(),这些都是些常见的例子,固然不局限于此。咱们大可将其当作一个普通的会在对象销毁或者脚本执行完毕的时候执行的函数。html
啰嗦那么多,仍是尽早提出今天的主要的问题:编程
<?php
class Test{ public function __destruct(){ echo "执行析构函数"; } } $test1=new Test; $test2=$test3=$test1;
unset($test1); echo "<hr/>";
这段脚本执行结果是什么?函数
在回答这个问题以前,回看我上面标示的几个字。咱们能够理所应当的认为在输出分隔线前 unset($test1) ,这样会调用析构函数,输出文字,至于 $test2,$test3 应该会在脚本执行完毕调用析构函数。也就是说,在分割线上面,会输出一段文字,分隔线下面会输出两段文字。 在这个时候,大能够小骄傲一下,毕竟本身懂得何时调用析构函数。但现实真是如此么?咱们能够看一下执行结果。post
嘿,他喵的,怎么就输出了一句啊???学习
其实咱们忽略了一个重要的前提条件,就是对象的赋值默认的是引用赋值。这一点不少人没有注意到,但愿初学者能多多注意一下。url
那么既然是引用赋值,结合咱们对普通变量的理解,咱们很快想到,三个变量名指向同一块存储地址。那么既然如此的话, unset($test1) 起到的是什么做用???破坏变量指向存储地址仍是破坏存储地址存储的内容?spa
了解unset()函数用法的请直觉跳过本段。code
想着这蛋疼的问题,莫不如去查看手册。htm
一样是传递引用,毁掉的仅仅是变量名指向存储地址。结合日常unset()的做用,咱们能够这么描述,当多个变量名或者对象名指向一块存储地址时,unset()函数的做用仅仅是销毁变量名和存储地址的指向而已,当仅有一个变量名或者对象名,unset销毁的是指定的存储地址上的内容。
咱们能够想象真实的存储内容是一台电视。多我的(多个变量名或对象名)在看一台电视。unset()后,一我的不看了,离开了,电视还开着。当只有一我的看电视的时候,unset()后,人离开的时候,要把电视关了 ,也就是释放占用的存储空间。对这部份内容感兴趣的话也能够看一下《php 递归函数的三种实现方式》。
好的,回归主题。 unset($test1) 后, 原来的对象还在。当输出分割线后,脚本执行完毕,调用析构函数。 由于对象只有一个,调用析构函数也只调用一次。输出如上结果也就理所应当。
其余几个相关的有意思的问题:在程序中调用析构函数的方法还有不少。不管是设置对象为null,仍是false,其他的对象依旧不受影响。这和普通变量仍是有区别的。(unset()函数的效果是同样的)。有兴趣的话能够试试。
另外说一个比较囧的事情:咱们都知道构造函数能够使用__construct(),却忽视了同名构造函数。因此,你们仍是留心一下。