使用数字键的Reflection :: getProperties()的奇怪行为

时间:2013-03-28 00:43:09

标签: php object reflection properties

$obj = (object)array('a', 'b', 'c');
$refl = new \ReflectionObject($obj);
$props = $refl->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED);    

foreach($props as $prop)
  print $prop->name;

打印一些奇怪的名称,例如linefileline(而不是1,2,3)。为什么?我知道名字是无效的,因为它们是数字,但为什么我会得到这些随机字符串?

get_object_vars($obj)没有显示任何内容,print_r((array)$obj)实际上正确打印了值。


如果Reflection无法显示数字属性,有什么方法可以让它忽略它们吗?


它也发生在许多SPL处理器上(例如ArrayObject s,SplFixedArray s,SplHeap s)。显然,这种行为仅存在于某些PHP 5.3版本中。 PHP 5.4没有显示。


Related PHP bug以及我对解决方案的看法(property_exists忽略无效名称):

if(version_compare(PHP_VERSION, '5.4') < 0){
  $props = array_filter($props, function($prop) use($obj){
    return !$prop->isPublic() || property_exists($obj, $prop->name);
  });
}

2 个答案:

答案 0 :(得分:1)

将数组转换为对象会将数组键转换为属性名称,将值转换为其值。

您的数组有数字键。您的对象具有数字属性。这有点无效。

你真的想要:

$obj = (object) array('a'=> null, 'b' => null, 'c'=> null);

答案 1 :(得分:1)

It's a won't fix bug... or strange php behavior。因此,如果您不确定其中的数字键,则无法使用对象类型转换。使用类似这样的东西

$obj = new \stdClass();
foreach($array as $key=>$value)
    $obj->{$key} = $value;

你可以使用奇怪的php行为中的另一个脏技巧。获得所有属性而不反思。

$obj = (object) array('a', 'b', 'c');
$obj->{0}='asd';
while (list($field, $value) = each($obj))
    {
    var_dump($field, $value);
    }

此外,我认为只有stdClass对象才会出现此问题。