Как преобразовать объект в массив без префикса имени класса в PHP?
class Teste{ private $a; private $b; function __construct($a, $b) { $this->a = $a; $this->b = $b; } } var_dump((array)(new Teste('foo','bar')));
Результат:
array ' Teste a' => string 'foo' (length=3) ' Teste b' => string 'bar' (length=3)
Ожидаемое:
array ( a => 'foo' b => 'bar' )
Из руководства :
Если объект преобразуется в массив, результатом является массив, элементами которого являются свойства объекта. Ключи – это имена переменных-членов, с несколькими заметными исключениями: целочисленные свойства недоступны; частные переменные имеют имя класса, добавленное к имени переменной ; защищенные переменные имеют «*», добавленные к имени переменной. Эти предварительные значения имеют нулевые байты с обеих сторон . Это может привести к неожиданному поведению:
Поэтому вы можете обойти проблему следующим образом:
$temp = (array)(new Teste('foo','bar')); $array = array(); foreach ($temp as $k => $v) { $k = preg_match('/^\x00(?:.*?)\x00(.+)/', $k, $matches) ? $matches[1] : $k; $array[$k] = $v; } var_dump($array);
Кажется странным, что нет возможности контролировать / отключать это поведение, поскольку нет риска столкновения.
«Префикс имени класса» является частью (внутреннего) имени свойства. Поскольку вы заявили, что как private
PHP нуждается в чем-то, чтобы отличить это от свойств $a
и $b
любого подкласса.
Самый простой способ обойти его: не делать их private
. Вместо этого вы можете объявить их protected
.
Однако это не решение в каждом случае, потому что обычно объявляется что-то как private
с намерением. Я рекомендую реализовать метод, который делает преобразование для вас. Это дает вам еще больший контроль над тем, как выглядит результирующий массив
public function toArray() { return array( 'a' => $this->a, 'b' => $this->b ); }
Насколько я знаю, PHP не имеет простого способа сделать то, что вы хотите. В большинстве языков этого нет. Вы должны смотреть в размышления. Взгляните на этот документ: http://www.php.net/manual/en/reflectionclass.getproperties.php
Я создал функцию, которая должна работать, как ожидалось:
function objectToArr($obj) { $result = array(); ReflectionClass $cls = new ReflectionClass($obj); $props = $cls->getProperties(); foreach ($props as $prop) { $result[$prop->getName()] = $prop->getValue($obj); } }
Вы можете использовать Reflection для решения этой задачи. Но, как обычно, это сильный индикатор того, что дизайн вашего класса несколько сломан. Однако:
function objectToArray($obj) { // Create a reflection object $refl = new ReflectionClass($obj); // Retrieve the properties and strip the ReflectionProperty objects down // to their values, accessing even private members. return array_map(function($prop) use ($obj) { $prop->setAccessible(true); return $prop->getValue($obj); }, $refl->getProperties()); } // Usage: $arr = objectToArray( new Foo() );