使用JS对象等引用操作PHP数组

时间:2015-11-01 14:06:47

标签: php arrays closures pass-by-reference lexical-scope

我在JavaScript中操作一个数组,如下所示。

http://ideone.com/vH43iD

<?php

$root = array(
    'nodes'=>array(
        '1'=>array(
            'id'=>'1',
            'nodes'=>array(
                '4'=>array(
                    'id'=>'4',
                    'nodes'=>array(
                        '5'=>array(
                            'id'=>'5',
                            'nodes'=>array()
                        )
                    )
                )
            )
        ),
        '2'=>array(
            'id'=>'2',
            'nodes'=>array()
        ),
        '3'=>array(
            'id'=>'3',
            'nodes'=>array()
        )
    )
);

foreach ($root['nodes'] as $_node_id => &$_root_node) {
    $_put_parent = function (&$_node) use (&$_put_parent) {
        foreach ($_node['nodes'] as $_sub_node_id => &$_sub_node) {
            $_put_parent($_sub_node);
            $_sub_node['parent'] = $_node;
        }
    };

    $_root_node['parent'] = null;
    $_put_parent($_root_node);
}

echo '<pre>';
var_dump($root['nodes']['1']['nodes']['4']);
var_dump($root['nodes']['1']['nodes']['4']['nodes']['5']['parent']);
echo '</pre>';

?>

输出:

array(3) {
  ["id"]=>
  string(1) "4"
  ["nodes"]=>
  &array(1) {
    [5]=>
    array(3) {
      ["id"]=>
      string(1) "5"
      ["nodes"]=>
      array(0) {
      }
      ["parent"]=>
      array(2) {
        ["id"]=>
        string(1) "4"
        ["nodes"]=>
        *RECURSION*
      }
    }
  }
  ["parent"]=>
  array(3) {
    ["id"]=>
    string(1) "1"
    ["nodes"]=>
    &array(1) {
      [4]=>
      *RECURSION*
    }
    ["parent"]=>
    NULL
  }
}
array(2) {
  ["id"]=>
  string(1) "4"
  ["nodes"]=>
  &array(1) {
    [5]=>
    array(3) {
      ["id"]=>
      string(1) "5"
      ["nodes"]=>
      array(0) {
      }
      ["parent"]=>
      *RECURSION*
    }
  }
}

$root['nodes']['1']['nodes']['4']['nodes']['5']['parent']应指向$root['nodes']['1']['nodes']['4'],但$root['nodes']['1']['nodes']['4']['nodes']['5']['parent']没有'父级'参考。

我经常在JavaScript中这样做,但我不明白php有什么问题。

谢谢。

1 个答案:

答案 0 :(得分:0)

我使用ArrayObject s解决了这个问题。

http://ideone.com/J79Wh6

<?php

$root = new ArrayObject(array(
    'nodes'=>new ArrayObject(array(
        '1'=>new ArrayObject(array(
            'id'=>'1',
            'nodes'=>new ArrayObject(array(
                '4'=>new ArrayObject(array(
                    'id'=>'4',
                    'nodes'=>new ArrayObject(array(
                        '5'=>new ArrayObject(array(
                            'id'=>'5',
                            'nodes'=>new ArrayObject(array())
                        ))
                    ))
                ))
            ))
        )),
        '2'=>array(
            'id'=>'2',
            'nodes'=>new ArrayObject(array())
        ),
        '3'=>new ArrayObject(array(
            'id'=>'3',
            'nodes'=>new ArrayObject(array())
        ))
    ))
));

foreach ($root['nodes'] as $_node_id => $_root_node) {
    $_put_parent = function ($_node) use (&$_put_parent) {
        foreach ($_node['nodes'] as $_sub_node_id => $_sub_node) {
            $_put_parent($_sub_node);
            $_sub_node['parent'] = $_node;
        }
    };

    $_root_node['parent'] = null;
    $_put_parent($_root_node);
}

echo '<pre>';
var_dump($root['nodes']['1']['nodes']['4']);
var_dump($root['nodes']['1']['nodes']['4']['nodes']['5']['parent']);
echo '</pre>';

?>

现在输出:

object(ArrayObject)[5]
  public 'id' => string '4' (length=1)
  public 'nodes' => 
    object(ArrayObject)[6]
      public 5 => 
        object(ArrayObject)[7]
          public 'id' => string '5' (length=1)
          public 'nodes' => 
            object(ArrayObject)[8]
              ...
          public 'parent' => 
            &object(ArrayObject)[5]
  public 'parent' => 
    object(ArrayObject)[3]
      public 'id' => string '1' (length=1)
      public 'nodes' => 
        object(ArrayObject)[4]
          public 4 => 
            &object(ArrayObject)[5]
      public 'parent' => null
object(ArrayObject)[5]
  public 'id' => string '4' (length=1)
  public 'nodes' => 
    object(ArrayObject)[6]
      public 5 => 
        object(ArrayObject)[7]
          public 'id' => string '5' (length=1)
          public 'nodes' => 
            object(ArrayObject)[8]
              ...
          public 'parent' => 
            &object(ArrayObject)[5]
  public 'parent' => 
    object(ArrayObject)[3]
      public 'id' => string '1' (length=1)
      public 'nodes' => 
        object(ArrayObject)[4]
          public 4 => 
            &object(ArrayObject)[5]
      public 'parent' => null