2011-01-25 69 views
25

有没有办法在PHP中将多维array转换为stdClass对象?PHP - 将数组递归到对象?

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

回答

45

至于我可以告诉大家,对于这个没有预置的解决方案,所以你可以滚你自己:

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; 
} 
+3

PHP数组可能有空键,但对象不能有空属性。这可能是值得更改`else`到`elseif($ k!=='')` – Andy 2013-05-08 16:07:43

+0

@Andy固定,谢谢! – 2013-05-08 16:50:12

+0

感谢您注意,只有用elseif才能完成! – Andy 2013-05-10 10:36:57

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

这将为数组中的空键生成致命错误(无法访问空属性)。观察[雅各布的回答中的strlen](http://stackoverflow.com/questions/4790453/php-recursive-array-to-object#answer-4790485) – 2016-07-26 10:53:17

30

我知道这个答案是来晚了,但我会张贴任何人谁是寻找一个解决方案。

而不是所有这些循环等,你可以使用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; 
} 

希望方便的功能,这可以帮助

0

这里做一个使用PHP内部就地深阵列到对象转换功能(浅)阵列到对象类型的投射机制。 仅在必要时才创建新对象,最大限度地减少数据重复。

function toObject($array) { 
    foreach ($array as $key=>$value) 
     if (is_array($value)) 
      $array[$key] = toObject($value); 
    return (object)$array; 
} 

警告 - 如果存在循环引用的风险,请勿使用此代码。

3
/** 
* 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; 
} 
0

这里是一个平滑的方式做到这一点,可以处理非常深度的关联数组,并不会覆盖不在数组中对象的属性。

<?php 

    function setPropsViaArray($a, $o) 
    { 
     foreach ($a as $k => $v) 
     { 
      if (is_array($v)) 
      { 
       $o->{$k} = setPropsViaArray($v, ! empty ($o->{$k}) ? $o->{$k} : new stdClass()); 
      } 
      else 
      { 
       $o->{$k} = $v; 
      } 
     } 
     return $o; 
    }; 

    setPropsViaArray($newArrayData, $existingObject); 
0

我能想出的最短:

array_walk_recursive($obj, function (&$val) { if (is_object($val)) $val = get_object_vars($val); }); 
2

一些张贴在这里的其他解决方案无法从地图({}在JS分辨顺序排列(这将是在JS [])。 )对于许多用例而言,重要的是要区分具有所有顺序数字键的PHP数组,这些数字键应该保留在没有数字键的PHP数组中,这些数字键应该转换为对象。 (我的解决方案未定义为不属于上述两类的阵列。)

json_decode(json_encode($x))方法确实处理这两种类型,但不是最快的解决方案。它仍然是不错的,虽然,共计为25μs每次运行在我的样本数据(平均超过1M运行,减去循环开销。)

基准我一对夫妇的递归转换器的变化,并结束了与以下。它重建所有数组和对象(执行深层复制),但似乎比替换解决方案更快地修改阵列。它的时钟频率为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); 
    } 
} 

这里是就地版本。这可能是在其中只有一小部分需要转换一些大的输入数据的速度更快,但在我的样本数据花了为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; 
    } 
} 

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

1

晚了,但只是想提一提,你可以使用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和json_decode功能都可以从PHP开始5.2

1

可以使用array_map递归:

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

工作非常适合我,因为它不投例如碳对象基本stdClass的(其中JSON编码/解码一样)

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