参照渡しを理解しようとしています。例えが悪いかもしれませんが、ニュートンの第 3 法則(作用反作用対)のようなものでしょうか?
たとえば、次のコードの場合
$a = 4;
$b = 2;
$n = 42;
$a = &$b;
は
$a=$n
と同じ$b=$n
?と の値が同じアドレスに格納されて$a
いませんか?$b
参照渡しを理解しようとしています。例えが悪いかもしれませんが、ニュートンの第 3 法則(作用反作用対)のようなものでしょうか?
たとえば、次のコードの場合
$a = 4;
$b = 2;
$n = 42;
$a = &$b;
は
$a=$n
と同じ$b=$n
?と の値が同じアドレスに格納されて$a
いませんか?$b
これらの変数を通常どおりに割り当てる場合:
$a = 1;
$b = 2;
$c = 3;
次に、関連付けは次のようになります。
a --> 1
b --> 2
c --> 3
さて、あなたがこのよう$c
にの参照にすると$a
:
$a = 1;
$b = 2;
$c = &$a;
次に、関連付けは次のようになります。
a --> 1 <--.
b --> 2 |
c --------/
つまり、同じ値$a
を指します。$c
どちらも同じ値を指しているため、どちらかの変数を変更でき、両方とも新しい値を指します。
$a = 5;
echo "$a $c"; // Output: "5 5"
$c = 10;
echo "$a $c"; // Output: "10 10"
はい、 に割り当て$n
た後$a
、$b
ポイント$n
します。
これは、と の両方を実行した後、同じメモリ ロケーションを参照し、参照変数 ( )$a=&$b
$a
$b
is_ref=1
になるためです。また、その特定のメモリ位置の参照カウント ( refcount
) は だけ増加し1
ます。 これらの参照のいずれかに割り当てる値は、両方とも同じ値を指します。
実行$a=$n
すると、 の値が$n
によって参照される場所に保存され$a
ます。そして、これは と同じ場所$b
です。
こちらの例をご覧ください。
$a
, $b
,$n
は異なる場所を指しています
php > $a = 4;
php > $b = 2;
php > xdebug_debug_zval('a'); // they are pointing different location
a: (refcount=1, is_ref=0)=int(4)
php > xdebug_debug_zval('b'); // they are pointing different location
b: (refcount=1, is_ref=0)=int(2)
php > $n = 42;
php > xdebug_debug_zval('n');
n: (refcount=1, is_ref=0)=int(42)
$a と$b
両方が参照になる
php > $a = &$b;
php > xdebug_debug_zval('b');
b: (refcount=2, is_ref=1)=int(2)
php > xdebug_debug_zval('a'); // a too
a: (refcount=2, is_ref=1)=int(2)
およびのいずれかへの参照ではなく、新しい値の割り当て$a
$b
php > $a = $n;
php > xdebug_debug_zval('a'); // a holds $n's value '42' now
a: (refcount=2, is_ref=1)=int(42)
php > xdebug_debug_zval('b'); // same for b
b: (refcount=2, is_ref=1)=int(42)
通常、変数$a
とを作成すると$b
、それぞれにデータが格納される一意のメモリアドレスがあります。
ただし、インタプリタにそのことを伝えると$a = &$b
、$aと$bのメモリアドレスが同じになります。$aまたは$bに何かを割り当てると、メモリ内の同じ場所にデータが格納されるため、どちらも同じ値をエコーします。
実験したい場合は、コマンドラインからPHPインタラクティブインタープリターを起動することをお勧めします。
php -a
php > $a = 1;
php > $b = 2;
php > echo $a . ' ' . $b;
1 2
php > $a = &$b;
php > echo $a . ' ' . $b;
2 2
php > $a = 1;
php > echo $a . ' ' . $b;
1 1
php > $b = 2;
php > echo $a . ' ' . $b;
2 2
$a = $b
&$b = $n
の値は同じですが、値がプリミティブ型 and であるため異なりますprimitive types pass by value
。
コードが参照を使用しているかどうかをテストする最も簡単な方法は、ソース変数の値を変更し、ターゲット変数がその値を変更するかどうかを確認することです。
$n = 1;
$a = $n;
$b = $n;
echo $a; // 1
echo $b; // 1
echo $n; // 1
$n = 2;
echo $a; // 1
echo $b; // 1
echo $n; // 2
でもobjects always are passed by reference
$n = new Object(1);
$a = $n;
$b = $n;
$n->newValue(5);
$a->printValue(); // 5
$b->printValue(); // 5
$a->newValue(7);
$b->printValue(); // 7