Я интегрирую 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 .= " "; } } }