有人可以解释PHP中这2个参考用法之间的区别吗?

vl4*_*409 6 php arrays tree reference

下面的代码说明了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();

?>
Run Code Online (Sandbox Code Playgroud)

第一个函数提供预期的结果,而第二个函数失败并声明递归循环:

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*
                )

    )

)
Run Code Online (Sandbox Code Playgroud)

奇怪的是,如果在第二个函数中,将使用中间变量从堆栈中获取值,结果再次正常.我不明白发生了什么.由于一次暗杀,我如何多次将根元素作为自己的孩子?

最初,我需要从XML构建树(使用sax解析器),并且希望在当前级别使用指向树节点的"当前根"并将其推入/从堆栈中弹出并向其添加子元素,但是,令人惊讶的是,由于上述两个功能所展示的问题,我未能实施此方案.

那么,这种方法有什么问题呢?

vl4*_*409 0

一张图片胜过1000个字。我花了一些时间才明白到底发生了什么。

我必须使用 Xdebug 正确转储内部数据并查看引用计数和写入时复制的效果。

第一篇文章中的代码问题在于该分配

$croot = array_pop($stack);

当 croot 为“level_1”时,通过复制完成,即 croot 的元素(与 level_1 相同)用堆栈中的数据填充,并且此操作后 croot 与原始根不同。

图片会更好地解释。

PHP 内存中的变量