Преобразование объекта PHP в ассоциативный массив

Я интегрирую API на свой сайт, который работает с данными, хранящимися в объектах, в то время как мой код написан с использованием массивов.

Мне нужна быстрая и грязная функция для преобразования объекта в массив.

Просто придумайте это

$array = (array) $yourObject; 

С http://www.php.net/manual/en/language.types.array.php

Если объект преобразуется в массив, результатом является массив, элементами которого являются свойства объекта. Ключи – это имена переменных-членов, с несколькими заметными исключениями: целочисленные свойства недоступны; частные переменные имеют имя класса, добавленное к имени переменной; защищенные переменные имеют «*», добавленные к имени переменной. Эти предварительные значения имеют нулевые байты с обеих сторон.

Пример: простой объект

 $object = new StdClass; $object->foo = 1; $object->bar = 2; var_dump( (array) $object ); 

Вывод:

 array(2) { 'foo' => int(1) 'bar' => int(2) } 

Пример: сложный объект

 class Foo { private $foo; protected $bar; public $baz; public function __construct() { $this->foo = 1; $this->bar = 2; $this->baz = new StdClass; } } var_dump( (array) new Foo ); 

Выход (с редактированием \ 0s для ясности):

 array(3) { '\0Foo\0foo' => int(1) '\0*\0bar' => int(2) 'baz' => class stdClass#2 (0) {} } 

Вывод с var_export вместо var_dump :

 array ( '' . "\0" . 'Foo' . "\0" . 'foo' => 1, '' . "\0" . '*' . "\0" . 'bar' => 2, 'baz' => stdClass::__set_state(array( )), ) 

В этом случае не будет выполняться глубокое кастинг графического объекта, и вам необходимо применить нулевые байты (как описано в цитате руководства) для доступа к любым непубличным атрибутам. Таким образом, это лучше всего работает при бросании объектов или объектов StdClass только с общедоступными свойствами. Для быстрого и грязного (что вы просили) все в порядке.

Также см. Это подробное сообщение в блоге:

Вы можете быстро преобразовать глубоко вложенные объекты в ассоциативные массивы, опираясь на поведение функций кодирования / декодирования JSON:

 $array = json_decode(json_encode($nested_object), true); 

С первого хита Google для « php-объекта для объединения массива » мы имеем следующее:

 function object_to_array($data) { if (is_array($data) || is_object($data)) { $result = array(); foreach ($data as $key => $value) { $result[$key] = object_to_array($value); } return $result; } return $data; } 

Источник на codenippets.joyent.com .

Если свойства объекта общедоступны, вы можете:

 $array = (array) $object; 

Если они являются частными или защищенными, у них будут имена странных ключей в массиве. Итак, в этом случае вам понадобится следующая функция:

 function dismount($object) { $reflectionClass = new ReflectionClass(get_class($object)); $array = array(); foreach ($reflectionClass->getProperties() as $property) { $property->setAccessible(true); $array[$property->getName()] = $property->getValue($object); $property->setAccessible(false); } return $array; } 

Для многомерного массива

 $array = json_decode(json_encode($objects),TRUE); 

Просто используйте его для многомерного массива

 $array = json_decode(json_encode($objects),TRUE); 

Вместо написания сложных функций мы можем просто использовать встроенные функции PHP json_encode () и json_decode () .

Сначала преобразуйте объект в JSON и верните его как массив.

json_decode() имеет второй параметр: возвратить ассоциативный массив, установить его в ИСТИНА.

 $array = json_decode(json_encode($nested_object), true); 

Все остальные ответы, размещенные здесь, работают только с публичными атрибутами. Вот одно решение, которое работает с javabean-подобными объектами с использованием отражений и геттеров:

 function entity2array($entity, $recursionDepth = 2) { $result = array(); $class = new ReflectionClass(get_class($entity)); foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { $methodName = $method->name; if (strpos($methodName, "get") === 0 && strlen($methodName) > 3) { $propertyName = lcfirst(substr($methodName, 3)); $value = $method->invoke($entity); if (is_object($value)) { if ($recursionDepth > 0) { $result[$propertyName] = $this->entity2array($value, $recursionDepth - 1); } else { $result[$propertyName] = "***"; //stop recursion } } else { $result[$propertyName] = $value; } } } return $result; } 
 class Test{ const A = 1; public $b = 'two'; private $c = test::A; public function __toArray(){ return call_user_func('get_object_vars', $this); } } $my_test = new Test(); var_dump((array)$my_test); var_dump($my_test->__toArray()); 

Вывод

 array(2) { ["b"]=> string(3) "two" ["Testc"]=> int(1) } array(1) { ["b"]=> string(3) "two" } 

Вот какой код:

 function object_to_array($data) { if ((! is_array($data)) and (! is_object($data))) return 'xxx'; //$data; $result = array(); $data = (array) $data; foreach ($data as $key => $value) { if (is_object($value)) $value = (array) $value; if (is_array($value)) $result[$key] = object_to_array($value); else $result[$key] = $value; } return $result; } 

Как насчет get_object_vars($obj) ? Кажется полезным, если вы хотите получить доступ к общедоступным свойствам объекта. http://www.php.net/function.get-object-vars

Если вы не хотите, чтобы «*» добавлялся к вашему массиву, вы можете просто сделать что-то вроде

 $json = json_encode($object); $array = json_decode($json, true); print_r($array); 

Это работает отлично и намного лучше, чем приведение типов.

Чтобы преобразовать объект в массив, просто введите его явно

 $name_of_array = (array) $name_of_object; 

Здравствуй,

Вот моя рекурсивная функция PHP для преобразования объектов PHP в ассоциативный массив

 // --------------------------------------------------------- // ----- object_to_array_recusive --- function (PHP) ------- // --------------------------------------------------------- // --- arg1: -- $object = PHP Object - required --- // --- arg2: -- $assoc = TRUE or FALSE - optional --- // --- arg3: -- $empty = '' (Empty String) - optional --- // --------------------------------------------------------- // ----- return: Array from Object --- (associative) ------- // --------------------------------------------------------- function object_to_array_recusive ( $object, $assoc=TRUE, $empty='' ) { $res_arr = array(); if (!empty($object)) { $arrObj = is_object($object) ? get_object_vars($object) : $object; $i=0; foreach ($arrObj as $key => $val) { $akey = ($assoc !== FALSE) ? $key : $i; if (is_array($val) || is_object($val)) { $res_arr[$akey] = (empty($val)) ? $empty : object_to_array_recusive($val); } else { $res_arr[$akey] = (empty($val)) ? $empty : (string)$val; } $i++; } } return $res_arr; } // --------------------------------------------------------- // --------------------------------------------------------- 

Пример использования:

 // ---- return associative array from object, ... use: $new_arr1 = object_to_array_recusive($my_object); // -- or -- // $new_arr1 = object_to_array_recusive($my_object,TRUE); // -- or -- // $new_arr1 = object_to_array_recusive($my_object,1); // ---- return numeric array from object, ... use: $new_arr2 = object_to_array_recusive($my_object,FALSE); 

Пользовательская функция для преобразования stdClass в массив:

 function objectToArray($d) { if (is_object($d)) { // Gets the properties of the given object // with get_object_vars function $d = get_object_vars($d); } if (is_array($d)) { /* * Return array converted to object * Using __FUNCTION__ (Magic constant) * for recursive call */ return array_map(__FUNCTION__, $d); } else { // Return array return $d; } } 

Еще одна настраиваемая функция для преобразования Array в stdClass:

 function arrayToObject($d) { if (is_array($d)) { /* * Return array converted to object * Using __FUNCTION__ (Magic constant) * for recursive call */ return (object) array_map(__FUNCTION__, $d); } else { // Return object return $d; } } 

Пример использования:

  // Create new stdClass Object $init = new stdClass; // Add some test data $init->foo = "Test data"; $init->bar = new stdClass; $init->bar->baaz = "Testing"; $init->bar->fooz = new stdClass; $init->bar->fooz->baz = "Testing again"; $init->foox = "Just test"; // Convert array to object and then object back to array $array = objectToArray($init); $object = arrayToObject($array); // Print objects and array print_r($init); echo "\n"; print_r($array); echo "\n"; print_r($object); 

Вы также можете создать функцию в PHP для преобразования массива объектов.

 function object_to_array($object) { return (array) $object; } 

Возможно, вы захотите сделать это, когда вы получите данные как объекты из баз данных ->

 // Suppose result is the end product from some query $query $result = $mysqli->query($query); $result = db_result_to_array($result); function db_result_to_array($result) { $res_array = array(); for ($count=0; $row = $result->fetch_assoc(); $count++) $res_array[$count] = $row; return $res_array; } 
 function readObject($object) { $name = get_class ($object); $name = str_replace('\\', "\\\\", $name); \\ Comment this line, if you dont use class namespaces approach in your project $raw = (array)$object; $attributes = array(); foreach ($raw as $attr => $val) { $attributes[preg_replace('('.$name.'|\*|)', '', $attr)] = $val; } return $attributes; } 

возвращает массив без специальных символов и имен классов

Тип отличает ваш объект к массиву.

 $arr = (array) $Obj; 

Это решит вашу проблему.

Преобразование и удаление раздражающих звезд:

 $array = (array) $object; foreach($array as $key => $val) { $new_array[str_replace('*_','',$key)] = $val; } 

Вероятно, это будет дешевле, чем использование отражений.

Прежде всего, если вам нужен массив из объекта, вы, вероятно, должны сначала представлять данные в виде массива. Думаю об этом.

Не используйте инструкции foreach или преобразования JSON. Если вы планируете это, снова вы работаете с структурой данных, а не с объектом.

Если вам действительно нужно, используйте ориентированный на объект подход, чтобы иметь чистый и основной код. Например:

Объект как массив

 class PersonArray implements \ArrayAccess, \IteratorAggregate { public function __construct(Person $person) { $this->person = $person; } // ... } 

Если вам нужны все свойства, используйте объект передачи

 class PersonTransferObject { private $person; public function __construct(Person $person) { $this->person = $person; } public function toArray() { return [ // 'name' => $this->person->getName(); ]; } } 

эта функция может преобразовать свойство объекта в array associfif

 function ObjetToArray($adminBar){ $reflector = new ReflectionObject($adminBar); $nodes = $reflector->getProperties(); $out=[]; foreach ($nodes as $node) { $nod=$reflector->getProperty($node->getName()); $nod->setAccessible(true); $out[$node->getName()]=$nod->getValue($adminBar); } return $out; } 

use> = php5

Некоторые изменения в коде «хорошо-knwon»

 /*** mixed Obj2Array(mixed Obj)***************************************/ static public function Obj2Array($_Obj) { if (is_object($_Obj)) $_Obj = get_object_vars($_Obj); return(is_array($_Obj) ? array_map(__METHOD__, $_Obj) : $_Obj); } // BW_Conv::Obj2Array 

Обратите внимание: если функция является членом класса (например, выше), вы должны изменить __FUNCTION__ на __METHOD__

 $Menu = new Admin_Model_DbTable_Menu(); $row = $Menu->fetchRow($Menu->select()->where('id = ?', $id)); $Addmenu = new Admin_Form_Addmenu(); $Addmenu->populate($row->toArray()); 

Здесь я создал метод objectToArray () , который также работает с рекурсивными объектами, например, когда $objectA содержит $objectB который снова указывает на $objectA .

Кроме того, я ограничил вывод публичными свойствами, используя ReflectionClass. Избавьтесь от него, если вам это не нужно.

  /** * Converts given object to array, recursively. * Just outputs public properties. * * @param object|array $object * @return array|string */ protected function objectToArray($object) { if (in_array($object, $this->usedObjects, TRUE)) { return '**recursive**'; } if (is_array($object) || is_object($object)) { if (is_object($object)) { $this->usedObjects[] = $object; } $result = array(); $reflectorClass = new \ReflectionClass(get_class($this)); foreach ($object as $key => $value) { if ($reflectorClass->hasProperty($key) && $reflectorClass->getProperty($key)->isPublic()) { $result[$key] = $this->objectToArray($value); } } return $result; } return $object; } 

Чтобы идентифицировать уже используемые объекты, я использую защищенное свойство в этом (абстрактном) классе с именем $this->usedObjects . Если найден рекурсивный вложенный объект, он будет заменен на строку **recursive** . В противном случае он потерпит неудачу из-за бесконечного цикла.

Этот ответ является лишь объединением различных ответов этого сообщения, но это решение для преобразования объекта PHP с общедоступными или частными свойствами с простыми значениями или массивами в ассоциативном массиве …

 function object_to_array($obj) { if (is_object($obj)) $obj = (array)$this->dismount($obj); if (is_array($obj)) { $new = array(); foreach ($obj as $key => $val) { $new[$key] = $this->object_to_array($val); } } else $new = $obj; return $new; } function dismount($object) { $reflectionClass = new \ReflectionClass(get_class($object)); $array = array(); foreach ($reflectionClass->getProperties() as $property) { $property->setAccessible(true); $array[$property->getName()] = $property->getValue($object); $property->setAccessible(false); } return $array; } 

Краткое решение @ SpYk3HH

 function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; } 

Также вы можете использовать компонент Symfony Serializer

 use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; $serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]); $array = json_decode($serializer->serialize($object, 'json'), true); 

Используя typecasting, вы можете решить свою проблему. Просто добавьте следующие строки к возвращаемому объекту:

 $arrObj = array(yourReturnedObject); 

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

 $arrObj['key'] = value; 

Поскольку многие люди находят этот поток из-за проблем с динамическим доступом к атрибутам объекта, я просто $valueRow->{"valueName"} , что вы можете сделать это в php: $valueRow->{"valueName"}

В Context (удаленный вывод HTML для удобства чтения):

 $valueRows = json_decode("{...}"); // rows of unordered values decoded from a json-object foreach($valueRows as $valueRow){ foreach($references as $reference){ if(isset($valueRow->{$reference->valueName})){ $tableHtml .= $valueRow->{$reference->valueName}; }else{ $tableHtml .= " "; } } }