$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
, file
和line
(而不是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);