PHP - 递归数组到对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4790453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 14:22:43  来源:igfitidea点击:

PHP - recursive Array to Object?

phpobjectmultidimensional-arraystdclass

提问by Peter

Is there a way to convert a multidimensional arrayto a stdClassobject in PHP?

有没有办法在PHP中将多维转换arraystdClass对象?

Casting as (object)doesn't seem to work recursively. json_decode(json_encode($array))produces the result I'm looking for, but there has to be a better way...

铸造 as(object)似乎不能递归地工作。 json_decode(json_encode($array))产生我正在寻找的结果,但必须有更好的方法......

回答by Jacob Relkin

As far as I can tell, there is no prebuilt solution for this, so you can just roll your own:

据我所知,没有针对此的预构建解决方案,因此您可以自行推出:

function array_to_object($array) {
  $obj = new stdClass;
  foreach($array as $k => $v) {
     if(strlen($k)) {
        if(is_array($v)) {
           $obj->{$k} = array_to_object($v); //RECURSION
        } else {
           $obj->{$k} = $v;
        }
     }
  }
  return $obj;
} 

回答by Ole

I know this answer is coming late but I'll post it for anyone who's looking for a solution.

我知道这个答案来晚了,但我会把它发布给任何正在寻找解决方案的人。

Instead of all this looping etc, you can use PHP's native json_* function. I've got a couple of handy functions that I use a lot

您可以使用 PHP 的本机 json_* 函数,而不是所有这些循环等。我有几个我经常使用的方便的功能

/**
 * Convert an array into a stdClass()
 * 
 * @param   array   $array  The array we want to convert
 * 
 * @return  object
 */
function arrayToObject($array)
{
    // First we convert the array to a json string
    $json = json_encode($array);

    // The we convert the json string to a stdClass()
    $object = json_decode($json);

    return $object;
}


/**
 * Convert a object to an array
 * 
 * @param   object  $object The object we want to convert
 * 
 * @return  array
 */
function objectToArray($object)
{
    // First we convert the object into a json string
    $json = json_encode($object);

    // Then we convert the json string to an array
    $array = json_decode($json, true);

    return $array;
}

Hope this can be helpful

希望这会有所帮助

回答by Priya

function toObject($array) {
    $obj = new stdClass();
    foreach ($array as $key => $val) {
        $obj->$key = is_array($val) ? toObject($val) : $val;
    }
    return $obj;
}

回答by MAChitgarha

You and many others have pointed to the JSON built-in functions, json_decode()and json_encode(). The method which you have mentioned works, but not completely: it won't convert indexed arrays to objects, and they will remain as indexed arrays. However, there is a trick to overcome this problem. You can use JSON_FORCE_OBJECTconstant:

您和许多其他人都指出了 JSON 内置函数json_decode()json_encode(). 您提到的方法有效,但不完全:它不会将索引数组转换为对象,它们将保留为索引数组。但是,有一个技巧可以克服这个问题。您可以使用JSON_FORCE_OBJECT常量:

// Converts an array to an object recursively
$object = json_decode(json_encode($array, JSON_FORCE_OBJECT));

Tip: Also, as mentioned here, you can convert an object to array recursively using JSON functions:

提示:另外,正如这里提到的,您可以使用 JSON 函数递归地将对象转换为数组:

// Converts an object to an array recursively
$array = json_decode(json_encode($object), true));    

回答by Arno van Oordt

You can use the array_maprecursively:

您可以array_map递归地使用:

public static function _arrayToObject($array) {
    return is_array($array) ? (object) array_map([__CLASS__, __METHOD__], $array) : $array;
}

Works perfect for me since it doesn't cast for example Carbon objects to a basic stdClass (which the json encode/decode does)

对我来说很完美,因为它不会将例如 Carbon 对象转换为基本的 stdClass(json 编码/解码所做的)

回答by Visakh B Sujathan

public static function _arrayToObject($array) {
    $json = json_encode($array);
    $object = json_decode($json);
    return $object
}

回答by Sunil

The simpliest way to convert an associative array to object is:

将关联数组转换为对象的最简单方法是:

First encode it in json, then decode it.

先用json编码,再解码。

like $objectArray = json_decode(json_encode($associtiveArray));

喜欢 $objectArray = json_decode(json_encode($associtiveArray));

回答by Dmitriy Sintsov

/**
 * Recursively converts associative arrays to stdClass while keeping integer keys subarrays as arrays
 * (lists of scalar values or collection of objects).
 */
function a2o( array $array ) {
    $resultObj = new \stdClass;
    $resultArr = array();
    $hasIntKeys = false;
    $hasStrKeys = false;
    foreach ( $array as $k => $v ) {
        if ( !$hasIntKeys ) {
            $hasIntKeys = is_int( $k );
        }
        if ( !$hasStrKeys ) {
            $hasStrKeys = is_string( $k );
        }
        if ( $hasIntKeys && $hasStrKeys ) {
            $e = new \Exception( 'Current level has both integer and string keys, thus it is impossible to keep array or convert to object' );
            $e->vars = array( 'level' => $array );
            throw $e;
        }
        if ( $hasStrKeys ) {
            $resultObj->{$k} = is_array( $v ) ? a2o( $v ) : $v;
        } else {
            $resultArr[$k] = is_array( $v ) ? a2o( $v ) : $v;
        }
    }
    return ($hasStrKeys) ? $resultObj : $resultArr;
} 

回答by Tobia

Some of the other solutions posted here fail to tell apart sequential arrays (what would be []in JS) from maps ({}in JS.) For many use cases it's important to tell apart PHP arrays that have all sequential numeric keys, which should be left as such, from PHP arrays that have no numeric keys, which should be converted to objects. (My solutions below are undefined for arrays that don't fall in the above two categories.)

此处发布的其他一些解决方案无法区分顺序数组([]在 JS 中是什么)和映射({}在 JS 中)。对于许多用例,区分具有所有顺序数字键的 PHP 数组很重要,这些数组应该保留为例如,来自没有数字键的 PHP 数组,应将其转换为对象。(对于不属于上述两类的数组,我的以下解决方案是未定义的。)

The json_decode(json_encode($x))method does handle the two types correctly, but is not the fastest solution. It's still decent though, totaling 25μsper run on my sample data (averaged over 1M runs, minus the loop overhead.)

json_decode(json_encode($x))方法确实正确处理了这两种类型,但不是最快的解决方案。尽管如此,它仍然不错,在我的示例数据上每次运行总计25μs(平均超过 100 万次运行,减去循环开销。)

I benchmarked a couple of variations of the recursive converter and ended up with the following. It rebuilds all arrays and objects (performing a deep copy) but seems to be faster than alternative solutions that modify the arrays in place. It clocks at 11μsper execution on my sample data:

我对递归转换器的几个变体进行了基准测试,结果如下。它重建所有数组和对象(执行深度复制),但似乎比修改数组的替代解决方案更快。它在我的示例数据上每次执行的时钟为11μs

function array_to_object($x) {
    if (!is_array($x)) {
        return $x;
    } elseif (is_numeric(key($x))) {
        return array_map(__FUNCTION__, $x);
    } else {
        return (object) array_map(__FUNCTION__, $x);
    }
}

Here is an in-place version. It may be faster on some large input data where only small parts need to be converted, but on my sample data it took 15μsper execution:

这是一个就地版本。对于一些只需要转换小部分的大型输入数据,它可能会更快,但在我的示例数据上,每次执行需要15μs

function array_to_object_inplace(&$x) {
    if (!is_array($x)) {
        return;
    }
    array_walk($x, __FUNCTION__);
    reset($x);
    if (!is_numeric(key($x))) {
        $x = (object) $x;
    }
}

I did not try out solutions using array_walk_recursive()

我没有尝试使用解决方案 array_walk_recursive()

回答by mhh1422

Late, but just wanted to mention that you can use the JSON encoding/decoding to convert fully from/to array:

晚了,但只想提一下,您可以使用 JSON 编码/解码来完全从/到数组转换:

//convert object $object into array
$array = json_decode(json_encode($object), true);
//convert array $array into object
$object = json_decode(json_encode($array));

json_encode and json_decode functions are available starting from php 5.2

json_encode 和 json_decode 函数从 php 5.2 开始可用