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']}";
为什么解释器对->
中的${…}
有偏见?
答案 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 "