PHP の参照のあれ
もっと単純にすると次の結果を比べると判りやすい。
<?php call_user_func(function(){ echo 'val_val' . PHP_EOL; $a = range(1, 100000); $m = memory_get_usage(); $b = $a; $c = $b; echo ' memory usage: ' . number_format(memory_get_usage() - $m) . PHP_EOL; }); call_user_func(function(){ echo 'ref_val' . PHP_EOL; $a = range(1, 100000); $m = memory_get_usage(); $b = &$a; $c = $b; echo ' memory usage: ' . number_format(memory_get_usage() - $m) . PHP_EOL; }); call_user_func(function(){ echo 'val_ref' . PHP_EOL; $a = range(1, 100000); $m = memory_get_usage(); $b = $a; $c = &$b; echo ' memory usage: ' . number_format(memory_get_usage() - $m) . PHP_EOL; }); call_user_func(function(){ echo 'ref_ref' . PHP_EOL; $a = range(1, 100000); $m = memory_get_usage(); $b = &$a; $c = &$b; echo ' memory usage: ' . number_format(memory_get_usage() - $m) . PHP_EOL; });
結果 ... 3v4l.org。
val_val memory usage: 48 ref_val memory usage: 9,848,776 val_ref memory usage: 9,848,776 ref_ref memory usage: 48
もしくは、refcount と is_ref がどのようになるかを比べてみたり。
<?php call_user_func(function(){ echo 'val_val' . PHP_EOL; $a = "xxx"; $b = $a; $c = $b; ob_start(function ($s) { return preg_replace('/^/m', " ", $s); }); xdebug_debug_zval('a', 'b', 'c'); ob_end_flush(); }); call_user_func(function(){ echo 'ref_val' . PHP_EOL; $a = "xxx"; $b = &$a; $c = $b; ob_start(function ($s) { return preg_replace('/^/m', " ", $s); }); xdebug_debug_zval('a', 'b', 'c'); ob_end_flush(); }); call_user_func(function(){ echo 'val_ref' . PHP_EOL; $a = "xxx"; $b = $a; $c = &$b; ob_start(function ($s) { return preg_replace('/^/m', " ", $s); }); xdebug_debug_zval('a', 'b', 'c'); ob_end_flush(); }); call_user_func(function(){ echo 'ref_ref' . PHP_EOL; $a = "xxx"; $b = &$a; $c = &$b; ob_start(function ($s) { return preg_replace('/^/m', " ", $s); }); xdebug_debug_zval('a', 'b', 'c'); ob_end_flush(); });
結果。
val_val a: (refcount=3, is_ref=0)='xxx' b: (refcount=3, is_ref=0)='xxx' c: (refcount=3, is_ref=0)='xxx' ref_val a: (refcount=2, is_ref=1)='xxx' b: (refcount=2, is_ref=1)='xxx' c: (refcount=1, is_ref=0)='xxx' val_ref a: (refcount=1, is_ref=0)='xxx' b: (refcount=2, is_ref=1)='xxx' c: (refcount=2, is_ref=1)='xxx' ref_ref a: (refcount=3, is_ref=1)='xxx' b: (refcount=3, is_ref=1)='xxx' c: (refcount=3, is_ref=1)='xxx'