Я интегрирую на свой веб-сайт API, который работает с данными, хранящимися в объектах, в то время как мой код написан с использованием массивов.
Мне нужна быстрая и безопасная функция для преобразования объекта в массив.
Ответ 1
Просто введите это:
$array = (array) $yourObject;
Из документации по массивам:
Если объект преобразуется в массив, результатом будет массив, элементами которого являются свойства объекта. Ключами являются имена переменных-членов, за некоторыми примечательными исключениями: целочисленные свойства недоступны; частные переменные имеют имя класса, добавляемое к имени переменной; защищенные переменные имеют '*', добавляемое к имени переменной. Эти добавленные значения имеют нулевые байты по обе стороны.
Пример: Простой объект
$object = new StdClass;
$object->foo = 1;
$object->bar = 2;
var_dump( (array) $object );
Вывод:
array(2) {
'foo' => int(1)
'bar' => int(2)
}
Пример: Сложный объект
класс 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 );
Вывод (отредактированным для ясности):
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 или объектов, имеющих только публичные свойства. Для быстрого и безопасного (то, о чем вы просили) это подходит.
Ответ 2
function object_to_array($data) {
if (is_array($data) || is_object($data)) {
$result = [];
foreach ($data as $key => $value) {
$result[$key] = (is_array($data) || is_object($data)) ? object_to_array($value) : $value;
}
return $result;
}
return $data;
}
Чтобы сравнить это с решением json_decode & json_encode, данный вариант кажется более быстрым. Вот случайный тест (с использованием простого измерения времени):
$obj = (object) [
'name' =>'Mike',
'surname' =>'Jovanson',
'age' =>'45',
'time' =>1234567890,
'country' =>'Germany',
];
##### 100 000 тактов ######
* json_decode(json_encode($var)) : 4.15 сек
* object_to_array($var) : 0.93 сек
Ответ 3
Если свойства вашего объекта являются общедоступными, вы можете:
$array = (array) $object;
Если же они имеют модификаторы private или protected, у них будут неопределенные имена ключей в массиве. Итак, в этом случае вам понадобится следующая функция:
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;
}
Ответ 4
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"
}
Ответ 5
Вот код:
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;
}
Web