在http://php.net/manual/en/language.operators.precedence.php网页上,第二高的优先级包含一个名为[
的左关联运算符。
我不明白。是[
用于访问/修改数组条目,如$myArray[23]
中所示?我无法想象任何代码片段,我们需要知道其他运算符的“优先级”,或者[
的“关联性”有用。
答案 0 :(得分:67)
这是一个非常有效的问题。
首先看看PHP应该首先评估的内容从来没有含糊不清
[
的右侧,因为括号需要关闭它,所以
中间的每个运算符都优先于开括号。
示例:
$a[1+2]
+
具有优先权,即必须首先评估 1 + 2 ,然后才能确定哪个 1 + 2
要从 $ a 中检索的元素。
但运算符优先级列表与此无关。
其次,有一个评估连续[]
对的顺序,如下所示:
$b[1][2]
PHP将首先评估$b[1]
,然后将[2]
应用于此。这是从左到右
评估是左关联性的目的。
但手头的问题不在于关联性,而在于关于其他运营商的优先级。
该列表指出clone
和new
运算符优先于[
,这不容易测试。
首先,将new
与方括号组合在一起的大多数结构都被视为无效
句法。例如,这两个陈述:
$a = new myClass()[0];
$a = new myClass[0];
会给出解析错误:
语法错误,意外' ['
PHP要求您添加括号以使语法有效。所以我们无法测试 像这样的优先规则。
但是还有另一种方法,通过使用包含类名的变量:
$a = new $test[0];
这个是有效的语法,但现在的挑战是创建一个创建一些东西的类 这就像一个数组。
这不是一件容易的事,因为对象属性的引用如下:obj->prop
,而不是
比如obj["prop"]
。然而,可以使用可以处理方括号的ArrayObject class。我们的想法是扩展这个类并重新定义offsetGet method以确保该类的新制作对象具有要返回的数组元素。
为了使对象可打印,我最终使用了魔法方法__toString,当需要将对象强制转换为字符串时执行该方法。
所以我想出了这个设置,定义了两个类似的类:
class T extends ArrayObject {
public function __toString() {
return "I am a T object";
}
public function offsetGet ($offset) {
return "I am a T object's array element";
}
}
class TestClass extends ArrayObject {
public function __toString() {
return "I am a TestClass object";
}
public function offsetGet ($offset) {
return "I am a TestClass object's array element";
}
}
$test = "TestClass";
通过这种设置,我们可以测试一些事情。
echo new $test;
此语句创建一个新的 TestClass 实例,然后需要将其转换为 字符串,因此在该新实例上调用 __ toString 方法,该实例返回:
我是TestClass对象
这是预期的。
echo (new $test)[0];
这里我们从相同的动作开始,因为括号强制首先执行new
操作。这次PHP不会将创建的对象转换为字符串,而是从中请求数组元素0。该请求由 offsetGet 方法回答,因此上述语句输出:
我是TestClass对象的数组元素
echo new ($test[0]);
这个想法是强制执行相反的顺序。遗憾的是,PHP不允许这种语法,因此必须将语句分成两部分才能获得预期的评估顺序:
$name = $test[0];
echo new $name;
所以现在首先执行[
,取值的第一个字符
$ test ,即" T" ,然后new
应用于此。这就是我的原因
还定义了一个 T 类。 echo
调用该实例上的 __ toString ,产生:
我是T对象
现在进行最后的测试,看看没有括号时的顺序是什么:
echo new $test[0];
这是有效的语法,并且......
输出结果为:
我是T对象
事实上,PHP在[
运算符之前应用了new
,尽管在
operator precedence table!
clone
与new
clone
运算符与[
具有相似的行为。奇怪的是,clone
和new
在语法规则方面并不完全相同。使用clone
重复测试2:
echo (clone $test)[0];
产生解析错误:
语法错误,意外' ['
但是使用clone
重复测试4表明[
优先于它。
@bishop告知,这会重现长期存在的文档错误#61513: "clone
operator precedence is wrong"。
答案 1 :(得分:5)
这只是意味着数组变量(左关联 - $ first)将在数组键之前进行评估(右关联 - $ second)
$first[$second]
当数组有多个维度时,这很有意义
$first[$second][$third][$fourth]
答案 2 :(得分:4)
在PHP中,您可以使用[]
初始化空数组,因此为了知道如何定义数组,下一个字符的优先级定义了如何初始化数组。
由于数组是语法结构的一部分,因此它在任何数学运算之前完成,因此它的优先级高于其他计算运算符。
var_dump([5, 6, 7] + [1, 2, 3, 4]); # 5674 - The array's must be known before applying the operator
但是说实话,我并不是真的理解这个问题。在大多数编程语言中,[
和]
与数组相关联,这是基本语法的一部分,始终具有高优先级(如果不是最高的)