5

如何在 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' )
4

4 回答 4

14

手册

如果将对象转换为数组,则结果是一个数组,其元素是对象的属性。键是成员变量名,有几个值得注意的例外:整数属性不可访问;私有变量在变量名前面加上类名;受保护的变量在变量名前有一个“*”。这些前置值在任一侧都有空字节。这可能会导致一些意外行为:

因此,您可以像这样解决这个问题:

$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);

没有办法控制/禁用这种行为似乎很奇怪,因为没有碰撞的风险。

于 2012-08-07T14:10:22.700 回答
3

“类名前缀”是属性(内部)名称的一部分。因为您将两者都声明为privatePHP 需要一些东西来将其与属性$a$b任何子类区分开来。

绕过它的最简单方法:不要让它们private. 您可以将它们声明为protected

但是,这并不是在所有情况下都可以解决的问题,因为通常人们会将某事声明为private有意图。我建议实施一种方法,为您进行转换。这使您可以更好地控制结果数组的外观

public function toArray() {
  return array(
    'a' => $this->a,
    'b' => $this->b
  );
}
于 2012-08-07T14:11:43.727 回答
2

据我所知,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);
    }
}
于 2012-08-07T14:16:24.870 回答
1

您可以使用反射来解决此任务。但像往常一样,这是一个强有力的指标,表明你的班级设计有些破损。然而:

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() );
于 2012-08-07T14:18:31.890 回答