【问题标题】:Searching a multidimensional array for objects在多维数组中搜索对象
【发布时间】:2012-07-28 01:07:32
【问题描述】:

我在 PHP 中有一个多维数组,希望能够搜索它并找到所有对象值。

我想这样做的原因是,当找到一个对象时,我可以通过在其上调用output() 方法将其替换为数组。 output() 方法使用get_object_vars() 将自身变成一个数组,然后返回。

这是一个手动实现我想要的示例(但只有 2 级深度):

// First level search...
foreach($array as $k => $v) {

    // Check if it's an array.
    if (is_array($v)) {

        // Second level search...
        foreach($v as $k2 => $v2) {

            // If it's an object - convert it!
            if (is_object($v2)) {
                $array[$k][$k2] = $array[$k][$k2]->output();
            }

        }

    }

    // If it's an object - convert it!
    if (is_object($v)) {
        $array[$k] = $array[$k]->output();
    }

}

【问题讨论】:

    标签: php arrays object recursion multidimensional-array


    【解决方案1】:

    Tim Cooper 的回答是错误的,因为函数必须有一个按引用而不是按值传递的参数。

    php > class Foo { public function output() { return "this was an object"; } }
    php > $a = array( 1 => array( 2 => array( 'foo', 'red', 1, new Foo() ) ) );
    php > array_walk_recursive( $a, function( $item, $key ) { 
        if ( is_object( $item ) ) { 
            $item = $item->output(); 
        }
    } );
    php > print_r( $a );
    Array
    (
        [1] => Array
            (
                [2] => Array
                    (
                        [0] => foo
                        [1] => red
                        [2] => 1
                        [3] => Foo Object
                            (
                            )
    
                    )
    
            )
    
    )
    

    与通过引用传递:

    php > array_walk_recursive( $a, function( &$item, $key ) { 
        if ( is_object( $item ) ) {             
            $item = $item->output();
        } 
    } );
    php > print_r( $a );
    Array
    (
        [1] => Array
            (
                [2] => Array
                    (
                        [0] => foo
                        [1] => red
                        [2] => 1
                        [3] => this was an object
                    )
    
            )
     )
    

    【讨论】:

    • 完美!蒂姆库珀的回答揭示了我所追求的那种功能(但我不知道存在) - 你的回答已经对其进行了调整以使其工作 - 谢谢!
    【解决方案2】:

    你只需要一个递归函数:

    function objects_to_arrays_recursive (&$array) {
      foreach ($array as &$member) {
        if (is_object($member)) {
          $member = $member->output();
        }
        if (is_array($member)) {
          objects_to_arrays_recursive($member);
        }
      }
    }
    

    这将调用每个对象的output() 方法并将结果存储在最初保存该对象的键中。

    注意事项

    • 一旦对象被转换,这将循环对象并转换子对象。您可能不想这样做,特别是如果您有循环引用,因为这会导致无限循环。只需将 2 个 ifs 更改为 if / elseif 即可避免这种情况。
    • 这不会检查给定对象是否有要调用的output() 方法。您可能应该添加一个is_a()/instanceof 支票。
    • 此函数通过引用获取其参数,这意味着输入数组将被修改。如果您需要保持原始数组完好无损,则需要先对其进行复制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-11
      • 1970-01-01
      • 2022-01-03
      • 2016-09-19
      相关资源
      最近更新 更多