带有 Int 变量的 PHP 对象


PHP objects with Int variables

我注意到PHP对象有些奇怪,但找不到记录的原因。

以下代码演示了该行为

<?php
$a = (object) array( 0 => 1 );
foreach($a as $b => $c) {
  $a->$b = ++$c;  //I'm expecting the key to be overwritten here
}
var_dump($a);
$var = 0;
var_dump($a->$var);
$var = "0";
var_dump($a->$var);

和输出

object(stdClass)#1 (2) {
  [0]=>
  int(1)
  ["0"]=>
  int(2)
}
int(2)
int(2)

使用->语法是否无法访问类的数字部分?

当你对数组执行(object)转换时,你会将该数组提升为匿名对象(即 stdClass)的内部属性列表。

在对象中索引属性

的方式与数组的索引方式略有不同;具体来说,对象属性名称始终被视为字符串,而数组索引则根据预期类型进行查找(例如,数字字符串被视为整数)。

上述行为不会影响foreach循环,因为那里不涉及哈希;就PHP而言,正在迭代一个常规数组。

要回答您的问题,是的,无法使用 -> 运算符访问原始数组中的数字键。为避免这种情况,您应该在执行强制转换之前从数组中删除数字索引。

在文档中很难找到这种行为,但可以在此处找到它的提示:

如果将对象转换为数组,则结果是一个数组,其元素是对象的属性。键是成员变量名称,但有一些值得注意的例外:整数属性无法访问...

仅供参考

在这种特殊情况下,您可以通过使用引用来规避此问题;不建议这样做,请遵循前面的建议,不要使用数字属性名称:

foreach ($a as &$c) {
    ++$c;
}
unset($c);

更新

2014-11-26:我已经更新了文档;实时页面将于本周五更新 - 提交。

stdClass处理数据非常松散,因为它是内部数组的对象表示(因此可以毫无问题地进行强制转换)。

$stdClassObject->property = "value";

该属性作为字符串处理,但在强制转换时,属性类型不会更改(这在某种程度上是可以理解的,就像您强制转换为对象然后再次转换为数组一样,您将丢失所有整数索引)。

我不认为他们可以做得更好,但你可以创建自己的 stdClass 替代品:-)