“怎么可能?”;[“是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];