【问题标题】:Strange behavior of Reflection::getProperties() with numeric keys带有数字键的 Reflection::getProperties() 的奇怪行为
【发布时间】:2013-03-18 07:51:12
【问题描述】:
$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) 实际上正确打印了值。


如果反射不能显示数字属性,有什么办法可以让它忽略它们?


它也发生在许多 SPL 交互器上(如 ArrayObjects、SplFixedArrays、SplHeaps)。显然这种行为只存在于某些 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);
  });
}

【问题讨论】:

  • ArrayObjects 呢?

标签: php object reflection properties


【解决方案1】:

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

您的数组有数字键。您的对象具有数字属性。哪些是无效的。

你真的想要:

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

【讨论】:

  • 数字字段名是合法的。 $obj2 = new \stdClass(); $obj2-&gt;{'0'} = 'a';
  • PHP 中没有。这是一个语法错误:$obj-&gt;2 = "yey";“语法错误,意外的 T_LNUMBER,需要 T_STRING 或 T_VARIABLE 或 '{' 或 '$'”
  • 您的示例没有使用整数值作为属性名称。它确实使用了一个内部带有数字的字符串。这就是区别。在数组内部,键总是整数,而不是字符串。因此,至少在用作属性名称时,数值是非常有问题的。
  • 一切都在定义中。 '0' 在 PHP 定义中是数字。 is_numeric('0');。但是还有另一个问题。对象具有字符串数字字段名称,但数组数字键始终是整数。
  • 附注我也可以使用整数,但它会被转换为字符串。看this article的底部。
【解决方案2】:

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

【讨论】:

  • 它也出现在任何 Iterator 对象上,例如 ArrayObject、SplFixedArray 等 :(
  • @OneTrickPony,你能打印例子吗?那我的把戏呢?
  • 它的工作方式似乎与我的 (array) cast 解决方案相同。经过更多谷歌搜索,我发现它是 5.3 中的bug
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-07
  • 2023-03-20
  • 2013-02-05
  • 1970-01-01
  • 2011-03-16
  • 2011-08-07
  • 1970-01-01
相关资源
最近更新 更多