在 PHP 中,是什么决定了类对象何时被销毁?
假设我们有类 CFoo
。在下面的示例中,什么时候调用 CFoo::__destruct()
?
function MyPHPFunc()
{
$foo = new CFoo();
. . .
// When/where/how does $foo get destroyed/deleted?
}
在此示例中,当脚本退出 MyPHPFunc
范围时,是否会调用析构函数,因为 $foo
将不再可访问?
Let's say that we have class CFoo
. In the following example when is CFoo::__destruct()
called?
function MyPHPFunc()
{
$foo = new CFoo();
. . .
// When/where/how does $foo get destroyed/deleted?
}
In this example would the destructor be called when the script exits the scope of MyPHPFunc
because $foo
would no longer be accessible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 PHP 中,所有值都保存在所谓的
zval
中。这些 zval 包含实际数据、类型信息以及引用计数(这对您的问题很重要)。看一下下面的代码片段:一旦
refcount
达到0
,zval
就会被释放并调用对象析构函数。以下是
refcount
达到0
的一些示例:取消设置
变量:但是:
离开函数(或方法)作用域
脚本执行结束
这些显然不是导致
refcount
减少的所有条件,而是您最常遇到的条件。另外我应该提到,由于 PHP 5.3 循环引用也会被检测到。因此,如果对象
$a
引用对象$b
且$b
引用$a
并且没有任何进一步的内容对$a
或$b
的引用,两者的refcount
将为1
,但它们仍将被释放(和__destruct
ed)。在这种情况下,尽管破坏的顺序是未定义的行为。In PHP all values are saved in so called
zval
s. Thosezval
s contain the actual data, type information and - this is important for your question - a reference count. Have a look at the following snippet:As soon as the
refcount
reaches0
thezval
is freed and the object destructor is called.Here are some examples of the
refcount
reaching0
:unset
ing a variable:But:
leaving function (or method) scope
script execution end
These obviously are not all conditions leading to a reduction of
refcount
, but the ones you will most commonly meet.Also I should mention that since PHP 5.3 circular references will be detected, too. So if object
$a
references object$b
and$b
references$a
and there aren't any further references to$a
or$b
therefcount
s of both will be1
, but they still will be freed (and__destruct
ed). In this case though the order of destruction is undefined behavior.如果您想查看实际操作过程,您可以在此处运行此代码。
If you want to see the process in action, you can run this code here.
这些信息位于手册中,尽管有些神秘:
含义:当对象被销毁(= 例如
unset()
)或脚本关闭时,将调用析构函数。其他有用信息:
The information is in the manual, albeit somewhat cryptic:
Meaning: The destructor will be called when the object gets destroyed (= e.g.
unset()
), or when the script shuts down.Additional useful info:
最好的了解方法是进行测试。
然而简单的答案是 __destruct 在垃圾清理期间被调用。粗略的,对任何人都没有帮助,因为垃圾清理是一个持续的过程,当没有范围可以调用它们时,它会清理局部变量。
然而,这里有一些示例代码,其结果充分解释了在脚本内部退出作用域时会发生什么。
这组奇怪的类函数和变量的输出是这样的,
这向我们展示了函数的末尾调用了 __destruct,就像 unset 一样,并且至少在实践中,脚本清理的末尾是按照创建的相反顺序完成的。
the best way to know is to test.
however the simple answer is that __destruct is called during garbage cleanup. coarse that does not help anyone as garbage cleanup is an ongoing process that cleans up local variables when there is no scope that can call them.
however here is some sample code, and the result which fully explains what happens when exiting scope internally to the script.
the output of this strange set of classes function and vars is this
this shows us that the end of the function calls the __destruct, as does unset, and that at least in practice that end of script cleanup is done in reverse order created.
如果创建类的实例并使用该对象。完成所有任务后,如果您调用析构函数并在下一行中再次使用相同的对象来执行其他任务,您将无法再使用。这意味着你的析构函数被成功调用
if create instance of a class and use the object.after finishing all your tasks if u call the destructor and again use the same object in the next line to perform some other task u will be no longer able to use. That means ur destructor is called successfully