以下のコードは、PHP 参照の奇妙な動作を示しています。
<?php
function this_works()
{
$root = array('name'=>'root', 'children'=>array());
$level_1 = array('name'=>'level_1', 'children'=>array());
$item1 = array('name'=>'level_2_1', 'children'=>array());
$item2 = array('name'=>'level_2_2', 'children'=>array());
$croot = &$root;
$croot['children'][] = &$level_1;
$croot = &$level_1;
$croot['children'][] = &$item1;
$croot['children'][] = &$item2;
$croot = &$root;
print_r($croot);
}
function this_fails()
{
$root = array('name'=>'root', 'children'=>array());
$level_1 = array('name'=>'level_1', 'children'=>array());
$item1 = array('name'=>'level_2_1', 'children'=>array());
$item2 = array('name'=>'level_2_2', 'children'=>array());
$croot = &$root;
$stack = array();
$croot['children'][] = &$level_1;
$crootref = &$croot;
array_push($stack, $crootref);
$croot = &$level_1;
$croot['children'][] = &$item1;
$croot['children'][] = &$item2;
# this works, assignment below - doesn't... WHY?
#$x = array_pop($stack);
#var_dump($x);
$croot = array_pop($stack);
print_r($croot);
}
this_works();
echo "------------------\n";
this_fails();
?>
最初の関数は期待される結果を提供しますが、2 番目の関数は失敗し、再帰ループについて主張します。
Array
(
[name] => root
[children] => Array
(
[0] => Array
(
[name] => level_1
[children] => Array
(
[0] => Array
(
[name] => level_2_1
[children] => Array
(
)
)
[1] => Array
(
[name] => level_2_2
[children] => Array
(
)
)
)
)
)
)
------------------
Array
(
[name] => root
[children] => Array
(
[0] => Array
(
[name] => root
[children] => Array
*RECURSION*
)
)
)
奇妙なことに、2 番目の関数で中間変数を使用してスタックから値を取得すると、結果は再び OK になります。何が起こっているのかわかりません。1 つの assinment により、ルート要素をそれ自体の子として何度も取得するにはどうすればよいですか?
もともと、XML からツリーを構築する必要があり (sax パーサーを使用)、現在のレベルのツリー ノードを指す「現在のルート」を作成し、それをスタックにプッシュ/ポップして子要素を追加するつもりでしたが、驚くべきことに、上記の 2 つの関数で示された問題により、このスキームを実装できませんでした。
では、そのようなアプローチの何が問題なのですか?