Как преобразовать объект в массив без префикса имени класса в PHP?

Как преобразовать объект в массив без префикса имени класса в 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() );