怎样才能在PHP语言规范中做一个操作符?

在http://php.net/manual/en/language.operators.precedence.php网页上,第二高优先级包含一个名为[的左关联运算符。

我不明白这一点。 它是[用于访问/修改数组条目,如在$myArray[23] ? 我无法想象任何需要知道其他操作符的“优先级”的代码片段,或者[有用的结合性]。

这是一个非常有效的问题。

1.优先于[…]

首先,在查看[右边的]时,PHP首先要评估什么是不明确的,因为括号需要closures一个,因此每个中间的操作符都优先于左括号。

例:

 $a[1+2] 

+具有优先权,即在PHP可以确定从$ a检索哪个元素之前,必须先评估第一个1 + 2

但是运营商的优先级列表并不在于此。

2.相关性

其次有一个评估连续对[]的顺序,就像这里:

 $b[1][2] 

PHP将首先评估$b[1] ,然后将[2]应用于此。 这是从左到右的评估,是左结合的目的

但是,手头的问题不是关于结社性,而是关于其他运营商的优先级。

3.优先于左侧的操作员

该列表指出clonenew操作符优先于[ ,这不容易testing。

首先,大部分将new的方括号组合在一起的构造被认为是无效的语法。 例如,这两个语句:

 $a = new myClass()[0]; $a = new myClass[0]; 

会给出一个parsing错误:

语法错误,意外的'['

PHP要求您添加括号以使语法有效。 所以我们不可能像这样testing优先规则。

但是另一种方法是使用一个包含类名的variables:

 $a = new $test[0]; 

有效的语法,但现在面临的挑战是创build一个类来创build类似数组的东西。

这不是微不足道的,因为对象属性是这样引用的: obj->prop ,不像obj["prop"] 。 但是可以使用可以处理方括号的ArrayObject类 。 这个想法是扩展这个类,并重新定义offsetGet方法 ,以确保该类的新build对象具有返回的数组元素。

为了使对象可打印,我最终使用了魔法方法__toString ,当一个对象需要被转换为一个string时被执行。

所以我想出了这个设置,定义了两个类似的类:

 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"; 

有了这个设置,我们可以testing一些东西。

testing1

 echo new $test; 

这个语句创build一个新的TestClass实例,然后需要将其转换为string,所以在新实例上调用__toString方法,该方法返回:

我是一个TestClass对象

这是预期的。

testing2

 echo (new $test)[0]; 

在这里,我们从相同的动作开始,因为括号会迫使new操作先执行。 这一次PHP不会将创build的对象转换为string,而是向它请求数组元素0。 这个请求由offsetGet方法回答,所以上面的语句输出:

我是一个TestClass对象的数组元素

testing3

 echo new ($test[0]); 

这个想法是强制执行的相反顺序。 令人遗憾的是,PHP不允许这种语法,所以为了得到预期的评估顺序,必须将语句分成两部分:

 $name = $test[0]; echo new $name; 

所以现在[首先执行,取$ test的值的第一个字符,即“T” ,然后再应用new 。 这就是为什么我也定义了一个T类。 echo在该实例上调用__toString ,这会产生:

我是一个T对象

现在进行最后的testing,看看没有括号的顺序是什么:

testing4

 echo new $test[0]; 

这是有效的语法,并…

4。结论

输出是:

我是一个T对象

所以实际上,PHP应用了[ new运算符之前,尽pipe运算符优先级表中已经说明了!

5.比较clonenew

clone操作符与[ 。 奇怪的是, clonenew语法在语法规则上并不完全相同。 用clone重复testing2:

 echo (clone $test)[0]; 

产生parsing错误:

语法错误,意外的'['

但是用clone重复的testing4显示[优先于它。

@bishop通知说,这再现了长期的文档错误#61513:“ clone运算符优先级错误” 。

它只是意味着数组variables(左结合性 – $第一)将在数组键之前被计算(右结合性 – $秒)

 $first[$second] 

当数组有多个维度时,这很有意义

 $first[$second][$third][$fourth] 

在PHP中,可以使用[]初始化空数组,以便知道如何定义数组,下一个字符的优先级定义了如何初始化数组。

由于数组是语法结构的一部分,所以在math运算之前就已经完成了,所以它比其他计算运算符具有更高的优先级。

 var_dump([5, 6, 7] + [1, 2, 3, 4]); # 5674 - The array's must be known before applying the operator 

不过,我真的不明白这个问题。 在大多数编程语言中, []都与数组关联,这些数组是基本语法的一部分,总是具有高优先级(如果不是最高的)