“怎么可能?”;[“是PHP语言规范中的运算符吗?”?
在网页上,第二高优先级包含一个名为“怎么可能?”;[“是PHP语言规范中的运算符吗?”?,php,specifications,Php,Specifications,在网页上,第二高优先级包含一个名为[的左关联运算符 我不明白。是不是像在$myArray[23]中那样,使用[来访问/修改数组项?我无法想象任何代码片段需要知道它与其他运算符的“优先级”,或者[将非常有用。在PHP中,可以使用[]初始化空数组,因此为了知道如何定义数组,下一个字符的优先级定义了如何初始化数组 由于数组是语法结构的一部分,所以它在进行任何数学运算之前就完成了,因此它的优先级高于其他计算运算符 var_dump([5, 6, 7] + [1, 2, 3, 4]); # 5674 -
[
的左关联运算符
我不明白。是不是像在
$myArray[23]
中那样,使用[
来访问/修改数组项?我无法想象任何代码片段需要知道它与其他运算符的“优先级”,或者[
将非常有用。在PHP中,可以使用[]
初始化空数组,因此为了知道如何定义数组,下一个字符的优先级定义了如何初始化数组
由于数组是语法结构的一部分,所以它在进行任何数学运算之前就完成了,因此它的优先级高于其他计算运算符
var_dump([5, 6, 7] + [1, 2, 3, 4]); # 5674 - The array's must be known before applying the operator
但是老实说,我并不真正理解这个问题。在大多数编程语言中,
[
和]
与数组相关联,数组是基本语法的一部分,总是具有高优先级(如果不是最高的话)它只是指数组变量(左关联-$first)将在数组键之前求值(右关联性-$second)
当数组有多个维度时,这很有意义
$first[$second][$third][$fourth]
这是一个非常有道理的问题 1.在[…]之间的优先权 首先,在查看 右侧的
[
,因为括号需要一个闭合的,所以
中间的每个运算符都优先于左括号
例如:
$a[1+2]
+
具有优先权,即必须先计算前1+2,然后PHP才能确定哪一个
要从$a检索的元素
但运算符优先级列表与此无关
2.结合性
其次,对连续的[]
对进行求值的顺序如下:
$b[1][2]
PHP将首先计算$b[1]
,然后对其应用[2]
。这是从左到右的
求值和是左关联的目的
但是现在的问题不是关于结合性,而是关于相对于其他操作符的优先级
3.优先于左侧的运算符
列表中指出,clone
和new
运算符的优先级高于[
,这不容易测试
首先,将new
与方括号相结合的大多数构造都被认为是无效的
语法。例如,这两个语句:
$a = new myClass()[0];
$a = new myClass[0];
将给出一个分析错误:
语法错误,意外的“[”
PHP要求您添加括号以使语法有效。因此我们无法进行测试
优先规则是这样的
但还有另一种方法,使用包含类名的变量:
$a = new $test[0];
这是有效的语法,但现在的挑战是创建一个创建某些内容的类
这就像一个数组
这不是一件小事,因为对象属性是这样引用的:obj->prop
,而不是
类似于obj[“prop”]
。但是可以使用可以处理方括号的。其思想是扩展此类并重新定义,以确保该类的新创建对象具有要返回的数组元素
为了使对象可打印,我最终使用了神奇的方法,当对象需要转换为字符串时执行该方法
所以我提出了这个设置,定义了两个类似的类:
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";
通过这种设置,我们可以测试一些东西
测试1
此语句创建一个新的TestClass实例,然后需要将其转换为
字符串,因此对该新实例调用u_toString方法,该实例返回:
我是一个TestClass对象
这是意料之中的
测试2
这里我们从相同的操作开始,因为括号强制首先执行new
操作。这次PHP不会将创建的对象转换为字符串,而是从中请求数组元素0。此请求由offsetGet方法响应,因此上述语句输出:
我是TestClass对象的数组元素
测试3
这样做的目的是强制执行相反的执行顺序。遗憾的是,PHP不允许使用这种语法,因此必须将语句一分为二才能获得预期的计算顺序:
$name = $test[0];
echo new $name;
现在首先执行[
,取
$test,即“T”,然后对其应用new
。这就是为什么我
还定义了一个T类。echo
调用该实例上的\uuuu toString,这将产生:
我是一个讨厌的人
现在是最后一个测试,看看没有括号时的顺序是什么:
测试4
这是有效的语法,并且
4.结论
输出为:
我是一个讨厌的人
因此,事实上,PHP在新的
操作符之前应用了[
,不管
!
5.将clone
与new
clone
操作符与[
组合时具有类似的行为。奇怪的是,clone
和new
在语法规则方面并不完全相同。使用clone
重复测试2:
echo (clone $test)[0];
产生分析错误:
语法错误,意外的“[”
但是使用clone
重复的测试4表明[
优先于它
@bishop告知,这复制了长期存在的文档错误。问题是:在表达式中是否有任何运算符可以位于
[
之前,PHP将在开始应用数组引用之前优先应用。根据引用的文档,“新建”和“克隆”可能是这样的运算符。问题可能是:这会产生什么实际后果?显然,不管怎样都没有,因为new和clone都是语言构造函数和[
和]<
echo (new $test)[0];
echo new ($test[0]);
$name = $test[0];
echo new $name;
echo new $test[0];
echo (clone $test)[0];