讓我們的代碼作爲基礎:(refcounting documentation)
$a = new ArrayObject();
$a['ID'] = 42;
$b = &$a['ID'];
$c = $a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
xdebug_debug_zval('c');
這給:
a:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=2, is_ref=1),int 42
b:
(refcount=2, is_ref=1),int 42
c:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=2, is_ref=1),int 42
至於你說: $a
是對象,$b
是$a['ID']
($a['ID']
和$b
:refcount=2, is_ref=1
)的參考號 和$ C is copy as a reference (since PHP5),所以$ c是$一個參考(它現在是相同的對象:refcount=2, is_ref=0
)
如果我們:$c['ID'] = 37;
我們得到:
a:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=1, is_ref=0),int 37
b:
(refcount=1, is_ref=0),int 42
c:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=1, is_ref=0),int 37
$c['ID']
被分配一個新int
所以=>
$b
成爲獨立的(refcount=1
和is_ref=0
),以及$a['ID']
和$c['ID']
但作爲$c
和$a
依賴,$a['ID']
和$c['ID']
取相同的值37。
現在,讓我們的基本代碼,我們做到:$c['ID'] &= 0;
UPDATE: 出乎意料的是,我們得到:
a:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=2, is_ref=1),int 0
b:
(refcount=2, is_ref=1),int 0
c:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=2, is_ref=1),int 0
代替(如:$c['ID'] = $c['ID'] & 0;
)
a:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=1, is_ref=0),int 0
b:
(refcount=1, is_ref=0),int 42
c:
(refcount=2, is_ref=0),
object(ArrayObject)[1]
public 'ID' => (refcount=1, is_ref=0),int 0
ArrayObject的實現了ArrayAccess這樣:
正如在註釋所述和documented here:
直接修改是一個在$ OBJ完全替換陣列維度的值,如[6] = 7.另一方面,間接修改只改變部分維度,或嘗試通過引用另一個變量來指定維度,如$ obj [6] [7] = 7或$ var = & $ obj [ 6]。用++進行增量並用 - 進行遞減也需要間接修改。
一個可能的答案:
「組合運算符(+ =, - =,& =,| =)可以擔任相同的方式(間接修改。)」:
refcount
和is_ref
不受影響,因此(在我們的情況下)所有 相關變量的值都會被修改。 ($c['ID']
=>$a['ID']
=>$b)
是的,我不認爲這是記錄。手冊只說++和 - 執行間接修改,從而觸發'ArrayAccess :: offsetGet()'而不是'ArrayAccess :: offsetSet()'。爲了一致起見,我想+ =, - =,和堂兄弟是以相同的方式實現的。 – cleong
@cleong我似乎無法在文檔中找到它。你能指出哪裏? – webmaster777