基本上,变量在PHP中有两种工作方式…
对于除对象以外的所有内容:
- 分配是按值进行的(如果您这样做,则意味着会进行复制
$a = $b
。 - 可以通过执行引用来实现
$a = &$b
(请注意,引用运算符对变量进行 *** 作,而不对赋值运算符进行 *** 作,因为您可以在其他地方使用它)… - 副本使用写时复制技术。因此,如果这样做
$a = $b
,则该变量将没有内存副本。但是,如果再这样做$a = 5;
,则将复制内存并将其覆盖。
对于对象:
- 通过对象引用进行分配。通过引用,它与普通变量并不完全相同(我将在后面解释原因)。
- 按值复制可以做到
$a = clone $b
。 - 可以通过做到
$a = &$b
这一点来实现引用,但是请注意,这与对象无关。您正在将$a
变量绑定到$b
变量。它是否是对象都没有关系。
那么,为什么对对象的分配没有真正引用呢?如果您这样做会发生什么:
$a = new stdclass();$b = $a;$a = 4;
什么
$b啊 好吧,
stdclass那是因为这不是写对变量的引用,而是写对象的引用。
$a = new stdclass();$a->foo = 'bar';$b = $a;$b->foo = 'baz';
什么
$a->foo啊 是
baz。这是因为,当您这样做时
$b =$a,您是在告诉PHP使用相同的对象实例(因此对象引用)。请注意,
$a和
$b不是相同的变量,但是它们都引用相同的对象。
一种思考方式是,将存储对象的所有变量都视为存储指向该对象的指针。因此,该对象位于其他地方。当您将
$a =$b在那里
$b是一个对象,你正在做的是复制该指针。实际变量仍然不相交。但是,当你这样做
$a =&$b,你存储一个指针
$b的内部
$a。现在,当您对其进行 *** 作时,
$a它会将指针链级联到基础对象。使用
clone运算符时,您要告诉PHP复制现有对象,并创建一个具有相同状态的新对象。因此,
clone实际上只是对变量进行按值复制…
因此,如果您注意到了,我说过该对象未存储在实际变量中。它存储在其他地方,变量中只存储了一个指针。因此,这意味着您可以(并且经常有)指向同一实例的多个变量。出于这个原因,内部对象表示形式包含
refcount(仅是指向它的变量数量的计数)。当对象的引用计数降至0(意味着指向该对象的所有变量都超出范围,或更改为其他变量)时,将对其进行垃圾回收(因为它不再可访问)…
您可以在文档中阅读有关参考和PHP的更多信息…
免责声明: 其中某些可能是某些概念的过度简化或模糊化。我的目的只是作为它们工作方式的指南,而不是内部发生的确切故障…
编辑:
哦,至于这是“笨拙的”,我认为不是。我认为这真的很有用。否则,您将在各处传递变量引用。当应用程序一个部分中的变量影响应用程序另一部分中的另一个变量时,这可能会产生一些非常有趣的错误。这不是因为它已通过,而是因为引用是沿直线进行的。
通常,我不会使用太多的变量引用。我很少发现他们有诚实的需求。但是我一直都使用对象引用。我使用它们太多了,我很高兴它们是默认值。否则,我需要编写一些运算符(由于
&表示变量引用,因此需要另一个表示对象引用)。考虑到我很少使用
clone,我会说99.9%的用例应使用对象引用(因此使运算符可用于频率较低的用例)…
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)