このコードをベースにしてみましょう: ( 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
の参照であり、 $cは参照としてのコピー (PHP5 以降)であるため、 $c は $a の参照です (現在は同じオブジェクトです : )$a['ID']
$a['ID']
$b
refcount=2, is_ref=1
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']
新しい so が割り当てられますint
=>
$b
独立する (refcount=1
とis_ref=0
) だけでなく、$a['ID']
と$c['ID']
しかし、$c
と$a
は従属関係に$a['ID']
あり$c['ID']
、同じ値 37 を取ります。
それでは、基本コードを取得してみましょう。$c['ID'] &= 0;
更新:予期せず、次のようになります。
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
代わりに: ( if: $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 を実装しているので:
コメントで述べ、ここに文書化されているように:
直接的な変更は、$obj[6] = 7 のように、配列次元の値を完全に置き換えるものです。一方、間接的な変更は、次元の一部のみを変更するか、参照によって次元を割り当てようとします。 $obj[6][7] = 7 または $var =& $obj[6] のような別の変数。++ によるインクリメントと -- によるデクリメントも、間接的な変更が必要な方法で実装されます。
可能な答え:
"複合演算子 (+=、-=、&=、|=) は同じように機能する可能性があります (間接的な変更)":
refcount
影響をis_ref
受けないため、(この場合) 関連するすべての変数の値が変更されます。( $c['ID']
=> $a['ID']
=>$b)