無料Wikiサービス | デモページ
検索

アクセス数
最近のコメント
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

phpの参照返値


ローカル変数を参照返値とすると、かならず実値辺値となります。ローカル変数はその関数のreturnで無効となりますから、このような実装は利にかなっているとも言えます。
<?php
       $a = &test();
       xdebug_debug_zval('a');

function        &test()
{
       $b = "hoge";

       return $b;
}
?>

[root@localhost test]# php a.php
a: (refcount=1, is_ref=0)='hoge'
グローバル(静的変数)では、期待する参照辺値となります。
<?php
       $b = "hoge";
       $a = &test();
       xdebug_debug_zval('a');

function        &test()
{
       global  $b;

       return $b;
}
?>

[root@localhost test]# php a.php
a: (refcount=2, is_ref=1)='hoge'
参照辺値とする場合、呼び出し/関数宣言で&を追加する必要があります。呼び出しの&は、結果の代入時の扱いで、関数宣言の&は、返り値領域に設定する時の取り扱いと解釈すればと思います。

関数宣言で&を付加しないと、返値領域へのテンポラリ変数に実値として設定され、それを参照として$aに設定するわけですが、しかしテンポラリ変数はtest()終了で無効となるため、実値として設定され、しかも無効になる故、新規にhogeを確保し、それにリンクします(refcount=1)。
<?php
       $b = "hoge";
       $a = &test();
       xdebug_debug_zval('a');

function        test()
{
       global  $b;

       return $b;
}
?>

[root@localhost test]# php a.php
a: (refcount=1, is_ref=0)='hoge'
呼び出しで&を付けないと、実値辺値となります。&test()の返値領域のテンポラリ変数へ参照としての$bを設定します。それを実値として$aに設定します。テンポラリ変数のリンク先は$b = "hoge"のhogeです。従ってテンポラリ変が無効になっても、リンク先が$b = "hoge"故、$aも$bのhogeをリンクしていて、refcount=2となっています。
<?php
       $b = "hoge";
       $a = test();
       xdebug_debug_zval('a');

function        &test()
{
       global  $b;

       return $b;
}
?>

[root@localhost test]# php a.php
a: (refcount=2, is_ref=0)='hoge'

追記

ローカル変数を参照返値とするのは、実装的に有り得ないことですが、phpでは適当に記述してもなんとなく動作してくれて、それ故参照の取り扱いがしっくりこなかったりしていました。思うにシンタックスとしてエラーとしてくれてた方がしっくりいくのが早かったのではと思ったりしています。なお、内容は推測ですが・・・。

最終更新 2013/09/13 17:42:16 - north
(2013/09/13 17:27:17 作成)