问题
How to convert (cast) Object to Array without Class Name prefix in PHP?
class Teste{
private $a;
private $b;
function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
}
var_dump((array)(new Teste('foo','bar')));
Result:
array
'�Teste�a' => string 'foo' (length=3)
'�Teste�b' => string 'bar' (length=3)
Expected:
array (
a => 'foo'
b => 'bar' )
回答1:
From the manual:
If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour:
You can therefore work around the issue like this:
$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);
It does seem odd that there is no way to control/disable this behaviour, since there is no risk of collisions.
回答2:
The "class name prefix" is part of the (internal) name of the property. Because you declared both as private PHP needs something to distinguish this from properties $a and $b of any subclass.
The easiest way to bypass it: Don't make them private. You can declare them as protected instead.
However, this isn't a solution in every case, because usually one declares something as private with an intention. I recommend to implement a method, that makes the conversion for you. This gives you even more control on how the resulting array looks like
public function toArray() {
return array(
'a' => $this->a,
'b' => $this->b
);
}
回答3:
As far as I know, PHP doesn't have a simple way to do what you want. Most languages don't. You should look into reflection. Take a look at this document: http://www.php.net/manual/en/reflectionclass.getproperties.php
I've made a function that should work as expected:
function objectToArr($obj)
{
$result = array();
ReflectionClass $cls = new ReflectionClass($obj);
$props = $cls->getProperties();
foreach ($props as $prop)
{
$result[$prop->getName()] = $prop->getValue($obj);
}
}
回答4:
You can use Reflection to solve this task. But as usual this is a strong indicator that your class design is somewhat broken. However:
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() );
来源:https://stackoverflow.com/questions/11847751/how-to-convert-cast-object-to-array-without-class-name-prefix-in-php