Получение свойств объекта в ассоциативный массив в php
Во время разработки может потребоваться изменить формат данных по каким либо причинам. Работать с объектами не всегда может быть удобно.
В php объект можно преобразовать в массив, таким образом, что свойства объекта станут индексами ассоциативного массива. Я нашел 2 способа для этого (дабы не раздувать пост фрагментами кода, результаты print_r() будут везде опущены, кому интересно, можете попробовать сами):
- Можно просто сменить тип переменной, которая содержит объект:
$a = new A(); // Создали некий объект A
$a = (array) $a; // Превратили объект в массивВ данном подходе есть одно но. У меня лично возникли проблемы с protected и privat свойствами объекта, индексы не видятся, хотя в сети нашел примеры, в которых показано, что защищенные свойства объекта попадают в массив, просто имя индекса берется не просто из имени свойства, а подставляется префикс, в зависимости от свойства protected или privat. У меняв отладчике индексы не отображаются совсем. При попытке вывести через print_r($a), индексы в виде иероглифов отображаются.
-
Второй способ преобразовать объект в массив - функция get_object_vars().
Но почему-то и с ней возникла неопределенность. В простом примере, который я набрасывал для проверки работы функции с защищенными свойствами (protected), функции возвращает массив только public свойств объекта:
class B {
protected $name = "Alex";
}class A extends B {
public $name2 = "Alex2";
}$a = new A();
$a = get_object_vars($a);
print_r($a);Но при попытке использовать в реальном коде проекта, где примерно такая же структура кода, как и в простом примере выше, функция возвращала мне и protected, и private свойства, которые содержатся в родительском классе. Вообщем встал на грабли...
После некоторых экспериментов выяснил то, что функция возвращает защищенные или только публичные (public) свойства объекта в зависимости от контекста вызова функции (кстати тоже самое касается 3 способа, получения свойств объекта в массив через цикл). Я не знаю баг это или так было задумано, но работает это так:
function publci_get_vars($obj){
return get_object_vars($obj);
}class B {
protected $nameProtected = "AlexProtected";
private $namePrivate = "AlexPrivate";
public $last = "NikolaevPublic";
}class A extends B {
public $namePublic = "AlexPublic";
private $lastPrivate = "NikolaevPrivate";
protected $lastprotected = "Nikolaevprotected";function get_vars(){
$all = get_object_vars($this); // врент все
$public = publci_get_vars($this); // вернет только public
return array($all, $public);
}
}$obj = new A();
$array = get_object_vars($obj); // вернет только public
$result = $obj->get_vars();print_r($array);
print_r($result);Еще бы попробовать как поведет себя функция при передачи объекта в функцию call_user_func() или call_user_func_array() в виде параметра. И что если вызывается через __call() метод, который находится в другом классе?
-
Третий способ получения свойств объекта в ассоциативный массив (или автоинкрементный) состоит в реализации простого цикла foreach:
$obj = new A();
$vars = array();
foreach ($obj as $name => $value){
$vars[$name] = $value;
}print_r($vars);
Причем если, как и во 2 способе, вызывать цикл непосредственно в теле метода объекта, который мы преобразум, то цикл пройдет и по защищенным свойствам объекта (protected и private), а не только по публичным свойства объекта (public).
Использовать преобразование объекта в массив стоит очень осторожно и то, что кажется на первый взгляд простым, понятным и очевидным может быть менее очевидным на самом деле. Возможно есть и другие способы получения свойств объекта в ассоциативный массив в php, но я о них пока не знаю. Зная эти небольшие нюансы, думаю не сложно будет получить только публичные или только защищенные свойства объекта.
ordPress
блог AlexPTS