• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

__construct() 和 __destory() 在 PHP 中需要注意的地方

php 搞代码 4年前 (2022-01-20) 13次浏览 已收录 0个评论

基本上所有的编程语言在类中都会有构造函数和析构函数的概念。构造函数是在函数实例创建时可以用来做一些初始化的工作,而析构函数则可以在实例销毁前做一些清理工作。相对来说,构造函数我们使用得非常多,而析构函数则一般会用在释放资源上,比如数据库链接、文件读写的句柄等。

构造函数与析构函数的使用

我们先来看看正常的构造与析构函数的使用:

class A{    public $name;    public function __construct($name)    {        $this->name = $name;        echo "A:构造函数被调用,{$this->name}", PHP_EOL;    }    public function __destruct()    {        echo "A:析构函数被调用,{$this->name}", PHP_EOL;    }}$a = new A('$a');echo '-----', PHP_EOL;class B extends A{    public function __construct($name)    {        $this->name = $name;        parent::__construct($name);        echo "B:构造函数被调用,{$this->name}", PHP_EOL;    }    public function __destruct()    {        parent::__destruct();        echo "B:析构函数被调用,{$this->name}", PHP_EOL;    }}class C extends A{    public function __construct($name)    {    <span>%本文来源gaodai#ma#com搞*代#码9网#</span><strong>搞gaodaima代码</strong>    $this->name = $name;        echo "C:构造函数被调用,{$this->name}", PHP_EOL;    }    public function __destruct()    {        echo "C:析构函数被调用,{$this->name}", PHP_EOL;    }}class D extends A{}// unset($a); // $a的析构提前// $a = null; // $a的析构提前$b = new B('$b');$c = new C('$c');$d = new D('$d');echo '-----', PHP_EOL;exit;// A:构造函数被调用,$a// -----// A:构造函数被调用,$b// B:构造函数被调用,$b// C:构造函数被调用,$c// A:构造函数被调用,$d// -----// A:析构函数被调用,$d// C:析构函数被调用,$c// A:析构函数被调用,$b// B:析构函数被调用,$b// A:析构函数被调用,$a

上面的代码是不是有一些内容和我们的预期不太一样?没事,我们一个一个来看:

子类如果重写了父类的构造或析构函数,如果不显式地使用parent::__constuct()调用父类的构造函数,那么父类的构造函数不会执行,如C类子类如果没有重写构造或析构函数,则默认调用父类的析构函数如果没显式地将变量置为NULL或者使用unset()的话,会在脚本执行完成后进行调用,调用顺序在测试代码中是类似于栈的形式先进后出(C->B->A,C先被析构),但在服务器环境中则不一定,也就是说顺序不一定固定

析构函数的引用问题

当对象中包含自身相互的引用时,想要通过设置为NULL或者unset()来调用析构函数可能会出现问题。

class E{    public $name;    public $obj;    public function __destruct()    {        echo "E:析构函数被调用," . $this->name, PHP_EOL;        echo '-----', PHP_EOL;    }}$e1 = new E();$e1->name = 'e1';$e2 = new E();$e2->name = 'e2';$e1->obj = $e2;$e2->obj = $e1;

类似于这样的代码,$e1和$e2都是E类的对象,他们又各自持有对方的引用。其实简单点来说的话,自己持有自己的引用都会出现类似的问题。

$e1 = new E();$e1->name = 'e1';$e2 = new E();$e2->name = 'e2';$e1->obj = $e2;$e2->obj = $e1;$e1 = null;$e2 = null;// gc_collect_cycles();$e3 = new E();$e3->name = 'e3';$e4 = new E();$e4->name = 'e4';$e3->obj = $e4;$e4->obj = $e3;$e3 = null;$e4 = null;echo 'E destory', PHP_EOL;

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:__construct() 和 __destory() 在 PHP 中需要注意的地方

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址