19

理由がわかります

$a = new ArrayObject();
$a['ID'] = 42;
$b = &$a['ID'];
$c = $a;
$c['ID'] = 37;
echo $a['ID']."\n";
echo $b."\n";
echo $c['ID']."\n";

出力 37、42、37

その間

$a = new ArrayObject();
$a['ID'] = 42;
$b = &$a['ID'];
$c = $a;
$b = 37;
echo $a['ID']."\n";
echo $b."\n";
echo $c['ID']."\n";

出力 37、37、37

どちらの場合も$b、 は への参照で$a['ID']あり$c、 は と同じオブジェクトへのポインタ$aです。

によって参照される値を代入すると$b変更されるため、 とが変更されると変更されます。$a['ID']$c['ID']$b$a['ID']

変更する$c['ID']と、新しい int が に割り当てられ$a['ID']$b参照され$a['ID']なくなります。

しかし、これは私を悩ませます

$a = new ArrayObject();
$a['ID'] = 42;
$b = &$a['ID'];
$c = $a;
$c['ID'] &= 0;
$c['ID'] |= 37;
echo $a['ID']."\n";
echo $b."\n";
echo $c['ID']."\n";

(出力 37、37、37)

これは定義された動作ですか?私はドキュメントでそれについて何も見ませんでした...

4

2 に答える 2

3

このコードをベースにしてみましょう: ( 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']$brefcount=2, is_ref=1refcount=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=1is_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)

于 2013-05-22T09:22:15.577 に答える