PHP:为什么“ $ {obj-> prop}”是解析错误,而“ $ obj-> prop”是合法的?

时间:2019-02-12 18:56:23

标签: php parsing string-formatting

PHP 7.3.2

当解析PHP的双引号字符串中的变量时,我发现一个奇怪的解析错误:

echo "${obj->prop}"; // Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR)

// But this is legal:
echo "$obj->prop";

// And, for instance, all these are legal as well:
echo "${arr['key']}";
echo "${arr[0]}";
echo "${arr['0']}";

为什么解释器对->中的${…}有偏见?

1 个答案:

答案 0 :(得分:1)

首先,像这样的花括号不是复杂变量解析语法的替代形式。

"$var""${var}"是简单语法,而"{$var}"是复杂语法。

在简单的语法中,解释器严格地在寻找变量名,而不是表达式,并且大括号仅用于指示名称的结尾,以防万一您有"${var}othertext"之类的东西。手册说明

  

如果遇到美元符号($),则解析器将贪婪地获取尽可能多的令牌以形成有效的变量名。用大括号括住变量名称,以明确指定名称的结尾。

解释器并没有特别针对->中的${…}造成偏见,实际上,解释器对于${…}中认为有效的变量名非常严格,并且为访问单个变量设置了一个例外。阵列键。

例如,您不能做"${var['a']['b']}"

在解释代码的第一步中,当对字符串进行标记时,${是标记T_DOLLAR_OPEN_CURLY_BRACES,它将扫描器设置为“寻找变量名”状态。在这种状态下,唯一会被识别为变量名的是有效标签,后跟方括号或大括号。

标记数组键示例如下:

source: "           ${                      arr         [             'key'             ]  }  "
tokens: " T_DOLLAR_OPEN_CURLY_BRACES  T_STRING_VARNAME  [  T_CONSTANT_ENCAPSED_STRING   ]  }  "

对象属性示例如下:

source: "           ${                     obj            ->             prop    }  "
tokens: " T_DOLLAR_OPEN_CURLY_BRACES    T_STRING   T_OBJECT_OPERATOR   T_STRING  }  "

解析错误会在下一步发生,将对象运算符应用于字符串,这是意外错误。

使用不带花括号的简单语法,您会得到这些标记,它们可以正常工作:

source: "     $obj            ->            prop   "
tokens: "  T_VARIABLE  T_OBJECT_OPERATOR  T_STRING "