我是C++/Python/Java中PHP的新用户。在PHP中,有一个内置的数组类型,在我插入一个新对象或旧对象的副本后,我如何证明数组是同一个数组?在C++/Python/Java中,我可以使用对象地址、id()或哈希代码来测试对象是否相同,如何在PHP中进行相同的测试?
<?php
$a['0'] = "a";
$a['1'] = 'b'; //here, $a is a new copied one or just a reference to the old?
?>
好的,我更新了我的问题,实际上,没有具体的问题。我只是想知道数组对象在插入新值之前和之后是否保持不变。在Python中,我可以进行这样的测试:
a = [1]
print id(a)
a.append(2)
print id(a)
顺便说一句,这是Python中的id()函数手册。
id(...)
id(object) -> integer
Return the identity of an object. This is guaranteed to be unique among
simultaneously existing objects. (Hint: it's the object's memory address.)
代码更新:
# -*- coding: utf-8 -*-
a = [1, 2, 3]
b = [1, 2, 3]
print id(a)
print id(b) //the id(b) is not same as id(a), so a and b has same content, but they both own their own values in the memory
c = a // c is a reference to a
c.append(4)
print c
print a //after appending a new value(which means insert a new value to array), a has same value as c
所以问题是我可以通过C++/Python/Java中的代码来证明内存布局,我想确保我是否可以在PHP中做同样的事情。
默认情况下,在PHP中,只有对象是通过引用分配的。其他所有内容(包括数组)都是按值分配的。使两个变量指向同一数组的唯一方法是使用&
运算符显式设置引用。参考文献解释一章对这个主题进行了很好的概述。
在对象的情况下,即使使用简单的var_dump()
:,也可以很容易地发现引用
$a = new DateTime;
$b = $a;
$c = clone $a;
var_dump($a, $b, $c);
object(DateTime)#1 (3) {
["date"]=>
string(26) "2016-03-29 10:18:28.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Madrid"
}
object(DateTime)#1 (3) {
["date"]=>
string(26) "2016-03-29 10:18:28.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Madrid"
}
object(DateTime)#2 (3) {
["date"]=>
string(26) "2016-03-29 10:18:28.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Madrid"
}
请注意$a
和$b
共享的#1
标识符。
使用其他类型一点也不琐碎。在上述章节的"发现引用"部分,有一条用户评论,其中包含一些你可能想检查的复杂代码,尽管它很旧。
是的,当您修改数组的内容时,数组仍然是相同的"对象"(不是PHP所称的,而是概念上的)。复印件("软拷贝"、写拷贝)仅在时制作
- 将数组分配给另一个变量,而不使用引用(
=&
) - 在没有引用的情况下将其传递到函数中
return
它来自一个没有引用的函数
(这实际上是一回事:将其分配给另一个变量。)
除了@Anant发布的内容外,请参阅PHP引用计数,它说明了PHP的运行时引擎如何存储变量。
您将看到,即使是数组成员也是可以被其他对象、数组和变量指向(引用)的引用。因此,在C或Python中可能存在于内存中两个不同位置的两个"相同"数组,PHP将分别存储指向单个值的引用。
如果其中一个值被两个非引用变量指向,那么它将为更改后的值创建一个新的引用,现在每个变量都指向不同的引用。这是写时复制优化。
StackExchange编程的这篇文章也不错。第一个答案提供了更多好的链接:为什么很少使用数组引用。