怎样才能在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.优先于左侧的操作员
该列表指出clone
和new
操作符优先于[
,这不容易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.比较clone
与new
clone
操作符与[
。 奇怪的是, clone
和new
语法在语法规则上并不完全相同。 用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
不过,我真的不明白这个问题。 在大多数编程语言中, [
和]
都与数组关联,这些数组是基本语法的一部分,总是具有高优先级(如果不是最高的)