PHP – рекурсивный массив для объекта?

Есть ли способ преобразовать многомерный array в объект stdClass в PHP?

Кастинг как (object) не работает рекурсивно. json_decode(json_encode($array)) дает результат, который я ищу, но должен быть лучший способ …

Насколько я могу судить, для этого нет заранее подготовленного решения, поэтому вы можете просто сворачивать свои собственные:

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

Я знаю, что этот ответ приходит поздно, но я отправлю его всем, кто ищет решение.

Вместо всего этого цикла и т. Д. Вы можете использовать собственную функцию json_ * для PHP. У меня есть несколько удобных функций, которые я использую много

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

Надеюсь, это будет полезно

 function toObject($array) { $obj = new stdClass(); foreach ($array as $key => $val) { $obj->$key = is_array($val) ? toObject($val) : $val; } return $obj; } 
 /** * 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; } 

Некоторые из других решений, размещенных здесь, не могут отличить последовательные массивы (что было бы [] в JS) от карт ( {} в JS.) Для многих случаев использования важно рассказать обо всем массивах PHP, которые имеют все последовательные цифровые ключи, которые должен быть оставлен как таковой из массивов PHP, у которых нет числовых ключей, которые должны быть преобразованы в объекты. (Мои решения ниже не определены для массивов, которые не попадают в две вышеуказанные категории.)

Метод json_decode(json_encode($x)) корректно обрабатывает два типа, но не является самым быстрым решением. Тем не менее, он по-прежнему приличный, всего 25 мкс за один проход по моим образцовым данным (усредненный в течение 1 М , минус накладные расходы цикла).

Я сравнил пару вариаций рекурсивного конвертера и получил следующее. Он восстанавливает все массивы и объекты (выполняет глубокую копию), но, кажется, быстрее, чем альтернативные решения, которые изменяют массивы на месте. Он синхронизируется с частотой 11 мкс на выполнение по моим образцовым данным:

 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 мкс за выполнение:

 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() решения, используя array_walk_recursive()

Поздно, но просто хотел упомянуть, что вы можете использовать кодировку / декодирование 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

Ниже приведена функция, чтобы сделать преобразование массива в место на месте, использующее внутренний (неглубокий) внутренний механизм ввода-вывода типа «массив-объект». Он создает новые объекты только при необходимости, сводя к минимуму дублирование данных.

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

Предупреждение – не используйте этот код, если существует риск иметь круглые ссылки.

Вот гладкий способ сделать это, который может обрабатывать ассоциативный массив с большой глубиной и не перезаписывать свойства объекта, которые не находятся в массиве.

  <?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 ); 

Самое короткое, что я мог придумать:

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

Рекурсивно вы можете использовать array_map :

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

Прекрасно подходит для меня, поскольку он не отображает, например, объекты Carbon в базовый stdClass (который кодирует / декодирует json)

EDIT: эта функция представляет собой преобразование из объекта в массив.

От https://forrst.com/posts/PHP_Recursive_Object_to_Array_good_for_handling-0ka

 protected function object_to_array($obj) { $arrObj = is_object($obj) ? get_object_vars($obj) : $obj; foreach ($arrObj as $key => $val) { $val = (is_array($val) || is_object($val)) ? $this->object_to_array($val) : $val; $arr[$key] = $val; } return $arr; }