PHP の参照のあれ

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'