Web笔记 ·

PHP内存中的对象和引用简介

前言

本周收到的是一篇关于php内存中对象和引用相关的内容,篇幅短小,希望能帮助各位。

原文Introduction to Objects and References in PHP Memory

作者AGUSTIN VILLALBA

文章正文

我首次起草这篇文章是在备战我的PHP认证时,以便更好地了解PHP如何管理内存中的变量和对象。经过大量研究,我意识到找到我的问题的答案并不容易,所以一旦我完成了,我决定记录信息,以便人们可以在一个地方找到它。

在本文中,我将讨论如何在内存中控制对象和变量引用,因为这是一个可以产生讨论和不同意见的问题。需要考虑的一个问题是:“默认情况下,在PHP中对象传递是通过引用还是拷贝?”首先我要讲的是PHP中没有引用的内容;其次,我将讨论它们是什么,最后,我将研究垃圾收集器在PHP中是如何工作的。

执行类似$a = new Foo();语句时PHP如何在内存中创建对象?如今,内存并不像过去那样昂贵和有限。然而,对于优秀的PHP开发人员来说,了解和理解变量和对象是如何在其应用程序执行期间内部管理的,这一点仍然很重要。

 

PHP内存中的对象和引用简介

PHP中的对象和引用

许多人在PHP书籍和网站中表示,PHP中的对象默认是通过引用传递的。也有人说PHP中的对象是通过拷贝来分配的。为了弄清楚哪个语句是正确的,首先我们必须分析PHP中引用的是什么(以及什么不是)。

在PHP中什么是引用

比了解PHP中引用是什么更重要的是知道什么不是。在PHP中,引用不是c风格的指针;您不能像使用C指针那样使用引用来进行算术运算。为什么?因为,与C不同,PHP引用不是真正的内存地址,因为它们不是表示内存位置的数字。但是,什么是引用呢?

什么是 PHP中的引用?

在PHP中,引用是允许两个不同的变量读取和写入一个值的“别名” 。换句话说,它们是允许从具有不同名称的变量访问相同值的机制,使得它们的行为就像它们是相同的变量。请记住,在PHP中,变量名和变量的内容是两个完全不同的东西,它们被链接在所谓的“符号表”中。因此,当我们创建一个引用时,它只是在符号表中为该变量添加一个别名。假设我们有以下代码:

当执行上述语句时,变量$在内存中被创建,一个Foo 类型的对象在内存中被创建,同时一个条目被添加到符号表,表明变量$“引用”(或与之相关或指向,或者无论你想如何称呼它)Foo对象,但它本身不是一个指向该对象的指针。在概念上,我们有这样的例子:

PHP内存中的对象和引用简介

突击测验:如果我们执行此操作会发生什么?

并不是说 $b 成为了$a的引用;我们也不能说$b 是$a的拷贝。真正发生的是我们在内存中创建了一个新的变量$b,然后在符号表中添加了一个新的条目,表明变量$b也引用了和$a同样的Foo类型对象。所以,在视觉上,我们有一些类似于在这个例子中显示的东西:

PHP内存中的对象和引用简介

现在,如果我们执行:

我们将在内存中创建第三个变量$c ,但是在符号表中没有$c 的一个新条目。相反,在符号表中,它被记录为$c 是$a 的别名,因此它的行为是一样的,但是$c 不是指向$a 的指针——不像在C中,它创建了一些称为指针的指针。为了可视化,我们有一些类似于该图所示的内容:

PHP内存中的对象和引用简介

一旦我们要修改这三个变量的值(即写入一个新的值),PHP将不得不在内存中创建一个新的z_val结构,以分离变量$b$a/$c的内容,这样它们就可以独立地修改,而不会影响到其他的值。因此,如果我们将以下代码添加到前面的脚本中:

在内存中,我们将有一个如下图所示的情况:

PHP内存中的对象和引用简介

现在我们来考虑一个更完整的例子:

通过执行上述脚本生成的输出是:

PHP垃圾收集

最后,让我们看看PHP垃圾回收是如何工作的,因为它是在5.3版本中引入的。当PHP符号表中没有对该对象的引用时,PHP内存中的对象或变量将被PHP垃圾收集器删除。也就是说,从创建时间开始,PHP会维护对象的引用计数器,以便在脚本PHP执行期间,计数器根据“指向”的变量递增和减少引用计数器。一旦引用计数达到0(即,没有引用该对象,因此它不被使用),PHP将该对象标记为可移动的,以便在下一次PHP垃圾回收器中,它将从内存中删除,释放该空间以便重新使用。如果您想更详细地了解PHP垃圾回收的工作原理,请阅读这个文件。

最后的想法

我希望我已经阐明了PHP如何处理内存中的对象和变量,以及它如何“选择”应该由PHP垃圾收集器删除的对象。既然您已经了解了PHP如何在内存中管理变量和对象,那么请拿起您的笔记本,开始尝试一些代码来证明您已经学到了什么。试着使用变量和引用。另外,尝试改变一个变量的值会影响另一个引用它的值。这里有一个问题:在执行下面的代码后,$a和$b的值是多少?

如果您有兴趣阅读有关PHP性能特征的更多信息,请参阅Toptaler Vilson Duka的这篇文章。

了解基础知识

什么是PHP中的引用?

PHP中,引用是允许两个不同变量读取和写入单个值的“别名”。

PHP垃圾收集如何工作?

从创建时间开始,PHP会保留对对象的引用次数。当符号表中没有对该对象的引用时,PHP垃圾回收器会将其删除。

如何存储PHP内存引用?

PHP内存引用存储在名为符号表的键值存储中。

参与评论