带有数字键的Reflection::getProperties()的奇怪行为


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

打印一些奇怪的名字,比如line, fileline(而不是1,2,3),为什么?我意识到名字是无效的,因为它们是数字,但为什么我得到这些随机字符串?

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


如果反射不能显示数字属性,是否有任何方法可以使它忽略它们?


它也发生在许多SPL交互器上(如ArrayObject s, SplFixedArray s, SplHeap s),显然这种行为仅在某些PHP 5.3版本中存在。PHP 5.4没有显示任何内容。


相关的PHP错误和我的解决方案(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);
  });
}

这是一个无法修复的bug…或者奇怪的PHP行为。因此,如果不确定其中的数字键,就不能使用对象类型强制转换。使用像这样的

$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对象。

将数组强制转换为对象,将数组键转换为属性名,并将值转换为它们的值。

数组有数字键。你的对象有数字属性。这些都是无效的

你真的想:

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

相关内容

  • 没有找到相关文章

最新更新