警告:数组到字符串的转换,PHP 8.1 中未定义的属性试图调用对象的属性(在 PHP 5.5 中工作)
[注意:我在起草草案的过程中解决了这个问题 问题,但我想我会继续发布它以供将来使用 参考,因为我对所发出的警告进行了广泛的搜索 不提供解决方案,我认为这可能会帮助某人 未来。]
我有一个类 Thing
,它具有 $subthing_1
、$subthing_2
、$subthing_3
属性,所有属性哪些是对象:
class Thing {
...
public $subthing_1; // object of type Subthing
public $subthing_2; // object of type Subthing
public $subthing_3; // object of type Subthing
...
}
如果我想在 Thing 的实例中获取特定的 subthing,我可以这样做:
$thing->subthing_1
这样就可以很好地交付该 subthing。但我想概括调用哪些子事物,因此我有一个例程来获取特定子事物的名称(“subthing_1”、“subthing_2”或“subthing_3”),并将其存储在数组元素中的字符串中。因此,例如,$subthings[4]
具有字符串值“subthing_1”,并且
$thing->$subthings[4]
应提供与 $thing->subthing_1
。
如果我执行
var_dump($subthings[4]);
,
结果为
string(10) "subthing_1"
,对于
var_dump($thing);
>
结果是
object(Thing)#4 (87) {
...
["subthing_1"]=>
object(Category)#59 (12) {
...
}
...
}
一切都很好。但是,当我尝试执行此操作时:
var_dump($thing->$subthings[4]);
我得到以下信息:
警告:数组到字符串的转换...
警告:未定义的属性:Thing::$Array ...
警告:尝试访问 null 类型值的数组偏移量...
这让我困惑了很长一段时间,因为我看不到数组在哪里转换为字符串。 $subthings[4]
显然是一个字符串,如 var_dump($subthings[4])
所示,而不是一个数组。
对于在 PHP 5.5 中运行良好的代码,这些警告出现在 PHP 8.1 中。
最终我推断这两个 PHP 版本之间一定存在语法解释更改。
在 PHP 5.5 中,$thing->$subthings[4]
被解释为 $thing->{$subthings[4]}
,在 PHP 8.1 $thing->$subthings[4]
被解释为 {$thing->$subthings}[4]
。
我已经多次搜索了此更改的文档,但我想我没有找到正确的关键字。我希望这里有人可以提供有关记录此更改的答案。
[NOTE: I solved this problem in the course of drafting the
question, but figured I would proceed with posting it for future
reference, since my extensive searching on the warnings delivered did
not provide the solution and I figure this might help someone in the
future.]
I have a class Thing
that has properties $subthing_1
, $subthing_2
, $subthing_3
, all of which are objects:
class Thing {
...
public $subthing_1; // object of type Subthing
public $subthing_2; // object of type Subthing
public $subthing_3; // object of type Subthing
...
}
If I want to get a particular subthing in an instance of Thing, I can do:
$thing->subthing_1
and this works just fine to deliver that subthing. But I want to generalize which of the subthings are called, so I have a routine that gets the name of a particular subthing, either 'subthing_1', 'subthing_2', or 'subthing_3', and stores it in a string in an array element. Thus, $subthings[4]
has string value 'subthing_1', for example, and
$thing->$subthings[4]
should deliver exactly the same as $thing->subthing_1
.
If I do
var_dump($subthings[4]);
the result is
string(10) "subthing_1"
and for
var_dump($thing);
the result is
object(Thing)#4 (87) {
...
["subthing_1"]=>
object(Category)#59 (12) {
...
}
...
}
Which is all fine and good. However, when I try to do this:
var_dump($thing->$subthings[4]);
I get this:
Warning: Array to string conversion ...
Warning: Undefined property: Thing::$Array ...
Warning: Trying to access array offset on value of type null ...
This confused me for a long time, because I couldn't see where an array was being converted to a string. $subthings[4]
is clearly a string, as indicated by var_dump($subthings[4])
, not an array.
These warnings are appearing in PHP 8.1 for code that worked just fine in PHP 5.5.
Eventually I reasoned that there must have been a syntax interpretation change somewhere between these two PHP versions.
Whereas in PHP 5.5, $thing->$subthings[4]
is interpreted as $thing->{$subthings[4]}
, in PHP 8.1 $thing->$subthings[4]
is interpreted as {$thing->$subthings}[4]
.
I have searched high and low for documentation of this change, but I guess I am not hitting on the right keywords. I hope someone here can supply an answer for where this change is documented.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决方案是用大括号将数组括起来,以强制执行预期的(以前是默认的)解析顺序:
$thing->{$subthings[4]}
正如所指出的由 Don't Panic 提出,此评估语法更改记录在此处:
https://www.php。 net/manual/en/migration70.inknown.php#migration70.inknown.variable-handling.indirect
The SOLUTION is to surround the arrays with curly braces to enforce the expected (and formerly default) parse ordering:
$thing->{$subthings[4]}
As pointed out by Don't Panic, this evaluation syntax change is documented here:
https://www.php.net/manual/en/migration70.incompatible.php#migration70.incompatible.variable-handling.indirect