PHPは代入と参照の違い
http://ameblo.jp/nikko-inma/entry-11122429825.html
http://b.hatena.ne.jp/entry/ameblo.jp/nikko-inma/entry-11122429825.html
ふむふむ、なになに、PHPはクソ言語で、C++もVBもクソで、
きっちり書きたいときはC きっちり書きたいときはC きっちり書きたいときはC
イスから転げ落ちるわ!!!
ちょっとこれはPHPerとしては突っ込まざるを得ない。
いつ突っ込むかって?
とりあえず上記サイトで書かれてるサンプルじゃあ代入と参照が深く理解できないだろうってこともあり、その部分補足してみよう。
まずサンプルプログラム
<?php $a = 1; xdebug_debug_zval( 'a' ); $b = $a; //これはただの値の代入(ただしこので時点でbの変数コンテナは出来ない(copy on write)) xdebug_debug_zval( 'a' ); xdebug_debug_zval( 'b' ); $b = 111; //bの値を変えるとaの参照カウント(refcount)が1減って、新しくbの変数コンテナが作られる。 xdebug_debug_zval( 'a' ); xdebug_debug_zval( 'b' ); echo "----------------ここまで代入のみ、ここから参照(&)使うよ----------------\n"; $x = 1; xdebug_debug_zval( 'x' ); $y = &$x; //yはxの参照。ただの代入と違うのは、is_ref=1になること。 xdebug_debug_zval( 'x' ); xdebug_debug_zval( 'y' ); $y = 222; //yを変えると、参照先のxの値が変わるよ。 xdebug_debug_zval( 'x' ); xdebug_debug_zval( 'y' ); echo "----------------そんじゃあ配列で参照使ってみるよ----------------\n"; $ary = array( 1, 2, 3 ); xdebug_debug_zval( 'ary' ); $ref = &$ary[1]; //refは$ary[1]の参照を使うからis_ref=1になるよ xdebug_debug_zval( 'ary' ); xdebug_debug_zval( 'ref' ); $ref = 333; //refを変えると、参照先の$ary[1]の値が変わるよ。 xdebug_debug_zval( 'ary' ); xdebug_debug_zval( 'ref' );
次に実行結果
C:\Windows\System32>php -v PHP 5.4.7 (cli) (built: Sep 12 2012 23:48:31) Copyright (c) 1997-2012 The PHP Group Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans C:\Windows\System32>php C:\Users\bravewood\Desktop\test.php a: (refcount=1, is_ref=0)=1 a: (refcount=2, is_ref=0)=1 b: (refcount=2, is_ref=0)=1 a: (refcount=1, is_ref=0)=1 b: (refcount=1, is_ref=0)=111 ----------------ここまで代入のみ、ここから参照(&)使うよ---------------- x: (refcount=1, is_ref=0)=1 x: (refcount=2, is_ref=1)=1 y: (refcount=2, is_ref=1)=1 x: (refcount=2, is_ref=1)=222 y: (refcount=2, is_ref=1)=222 ----------------そんじゃあ配列で参照使ってみるよ--------------- ary: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=1, 1 => (refcount=1, is_ref=0)=2, 2 => (refcount=1, is_ref=0)=3) ary: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=1, 1 => (refcount=2, is_ref=1)=2, 2 => (refcount=1, is_ref=0)=3) ref: (refcount=2, is_ref=1)=2 ary: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=1, 1 => (refcount=2, is_ref=1)=333, 2 => (refcount=1, is_ref=0)=3) ref: (refcount=2, is_ref=1)=333
参考サイトからの抜粋
参照カウント法の原理
http://php.net/manual/ja/features.gc.refcounting-basics.php
変数を他の変数名に代入すると、refcount が増加します。 (中略) この時、refcount は 2 です。なぜなら、同じ変数コンテナが a と b にリンクされるからです。
代入演算子
http://php.net/manual/ja/language.operators.assignment.php
参照による代入とは、両方の変数が同じデータを指すようにするということです。 データのコピーは発生しません。
少し説明すると
忙しい人のためのまとめ
- $ref = &$array[1]; も $b = &$a; も本質的には同じこと
- 参照による代入とは、両方の変数が同じデータを指すようにするということ
- var_dumpじゃ参照関係が見えにくい
- xdebugのxdebug_debug_zvalを使うといい
そんなわけでPHPはクソ!!
bravewood the PHPer