首先,我了解编程和对象,但是在PHP中,以下内容对我而言意义不大。
在PHP中,我们使用&运算符检索对变量的引用。我理解引用是指使用不同变量引用相同“事物”的一种方式。如果我说例如
$b = 1;
$a =& $b;
$a = 3;
echo $b;
将输出3,因为对$ a所做的更改与对$ b所做的更改相同。反过来:
$b = 1;
$a = $b;
$a = 3;
echo $b;
应该输出1。
在这种情况下,为什么必须使用clone关键字?在我看来,如果我定下
$obj_a = $obj_b
那么对$ obj_a所做的更改不应影响$ obj_b,相反,$ obj_a =&$ obj_b应指向同一对象,因此对$
obj_a进行的更改将影响$ obj_b。
但是在PHP中似乎$ obj_a上的某些操作确实会影响$ obj_b,即使在没有引用操作符的情况下赋值也是如此($obj_a = $obj_b)
。今天,在使用DateTime对象工作时,这给我造成了一个令人沮丧的问题,而我最终通过基本完成的操作来解决了这个问题:
$obj_a = clone $obj_b
但是我编写的大多数php代码似乎都不需要这种情况下的显式克隆,没有它也可以正常工作。这里发生了什么?为什么PHP必须如此笨拙?
基本上,变量在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%的用例应使用对象引用(因此使运算符可用于频率较低的用例)…
问题内容: 越来越多地使用Python,并且不断看到在不同文件中设置的变量。有人可以解释这是什么吗? 问题答案: 这是该模块的公共对象的列表,由解释import 。它覆盖了默认的内容,即隐藏以下划线开头的所有内容。
如果C中有指针(char*names[])和指向指针的指针(char**cur_name=names);有指向指针的指针吗? 或者指向指针的指针只是一个链表?也许这是个愚蠢的问题,但我想知道答案。
问题内容: 有问题的代码在这里: 变量名称中美元符号的用途是什么,为什么不仅仅排除它呢? 问题答案: 变量中的“ $”对解释器而言没有什么特别的含义,就像下划线一样。 据我所见,许多使用jQuery的人(这就是您的示例代码对我而言的样子)倾向于给包含jQuery对象的变量加上$前缀,以便它们易于识别且不会与整数混淆。 jQuery中的美元符号函数是一个经常使用的库函数,因此最好使用短名称。
问题内容: 有两种通过play框架创建海关标签的方法。 通过在app / view / tags中定义一个Groovy模板 通过在类中直接扩展FastTag直接在纯Java中 没有最新的文件。 问题答案: 因此,类似于JavaExtensions通过扩展JavaExtensions类的工作方式,要创建FastTag,您需要创建一个扩展FastTags的类。您要作为标记执行的每个方法都必须符合以下方
我试图用以下代码指出声纳中的关键问题: 我也做了下面的更改,但仍然不起作用 请帮忙。
问题内容: 需要使用一对多和多对一关系。这是我对象中的双向关系,因此我可以从任一方向来回移动。是推荐的解决方法,但是,我听不懂。有人可以解释: 推荐的使用方式是什么? 它解决什么目的? 就我的示例而言,这是带有注释的类: 拥有许多 许多 属于一个 A 航空公司: 航空公司航班: 编辑: 数据库模式: AirlineFlights具有idAirline作为ForeignKey,而Airline没有i