How to convert (cast) Object to Array without Class Name prefix in PHP?

…衆ロ難τιáo~ 提交于 2020-01-01 03:29:17

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!