在字符串内的美元符号后使用花括号是不是错误

Posted

技术标签:

【中文标题】在字符串内的美元符号后使用花括号是不是错误【英文标题】:Is it wrong to use curly braces after the dollar sign inside strings在字符串内的美元符号后使用花括号是否错误 【发布时间】:2019-07-18 08:16:00 【问题描述】:

我试图了解复杂变量语法中两种可能的语法变体之间的区别。 php 允许两种变体:

$foo = 'bar';
$bar = "$foobar is allowed"; //or
$bar = "$foobar is allowed";

使用任一语法时都不会生成错误/警告/通知。我注意到两者之间没有区别,但是 PHP manual 仅显示 $foo 变体。 使用其他变体是错误的吗?它会给我带来什么问题吗?

【问题讨论】:

就个人而言,您示例的中间线具有误导性,我希望它被解释为 $foobar 而不是 barbar 用户对手动输入的评论表明$.. 的速度最低,php.net/manual/en/language.types.string.php#120160。 @Cutwow 这是一个很好的添加链接,但我不认为这是一个骗局,因为 OP 所询问的具体案例没有得到解决(至少没有任何深度) @Phil 在重新阅读另一篇文章中的答案后,我知道我的错误在哪里。正如您提到的,OP 的问题在另一篇文章中没有深入解释。我将删除我之前的评论。 @Cutwow 仍然是一个很好的参考。感谢您添加链接。 编辑:此链接 ~ Curly braces in string in PHP 【参考方案1】:

$... 是另一种用途的语法。它用于间接引用变量名。如果没有字符串插值,大括号或方括号中的文字名称将写为字符串文字,因此用引号括起来。然而,内插引号 not 使用 outside 花括号:

$bar = 'baz';

echo $bar , PHP_EOL;
echo $'bar' , PHP_EOL;

$arr = ['a' => 1, 'b' => ['x' => 'The X marks the point.']];
echo $arr['a'] , PHP_EOL;

// interpolation:
echo "$arr[a] / $arr['a']" , PHP_EOL;

你也可以使用函数来代替文字:

function foo()return "bar";

// Here we use the function return value as variable name.
// We need braces since without them the variable `$foo` would be expected
// to contain a callable

echo $foo() , PHP_EOL;

插值时,只有在表达式不明确时才需要用大括号括起来:

echo "$arr[b][x]", PHP_EOL;       // "Array[x]"     
echo "$arr['b']['x']", PHP_EOL; // "The X marks the point."

现在我们知道$... 是一个类似于"$arr[a]" 的简单“无括号”插值,因为花括号仅用于间接变量名称引用。不过,我们可以将它括在花括号中。

形成变量名的插值函数调用:

echo "$foo() / $foo()", PHP_EOL;
// "baz / baz" since foo() returns 'bar' and $bar contains 'baz'.

同样,"$bar" 等价于 $'bar',在花括号中:"$'bar'"


按照 cmets 的要求,

还有另一种花括号语法来引用数组键。

$someIdentifier'key'

这只是 PHP 常见数组语法 $array['key'] 的替代语法。

与后者相反,在间接变量名引用上,花括号紧跟在$ 或对象成员运算符-> 之后。为了让它更加神秘,我们可以将两者结合起来:

$bar['baz'] = 'array item';
echo $'ba' . 'r''ba'.'z';

相当于echo $bar['baz'];

PHP 的字符串插值真的很奇怪:"$bar" 有效,"$'bar'" 也有效,但 "$array['key']" 无效,"$array[key]" 有效,但 "$arraykey""$array'key'" 都无效.

结论

应该养成一直使用花括号插值语法的习惯。应该完全避免花括号数组键语法。 始终使用:

"$varname $array['key'] $funcname().'_array'['key']"

另见 PHP 文档:

Complex curly syntax

(区分)

Variable variables(也称为间接变量名引用)

Accessing array elements

方括号和花括号都可以互换使用来访问数组元素(例如,$array[42] 和 $array42 在上面的示例中都会做同样的事情)。

【讨论】:

你是说$bar['ba'.'z'] 等价于$bar'ba'.'z'?因为"$bar[baz]" 不等于"$barbaz"。 PHP 手册中是否记录了 curly 语法? 我也在网上找到了这篇文章,但没有官方信息:cowburn.info/2008/01/12/php-vars-curly-braces @Dharman 不,这是一个完全不同的话题,我不是说,但是,是的,你的例子实际上是等价的。 $array'key' 只是 PHP 常用语法 $array['key'] 的另一种语法。 array syntax 与 PHP 文档中调用的间接引用或“变量变量”相反:php.net/manual/en/language.variables.variable.php @Dharman 我已经扩展了我的解释,希望它可以减少混淆。【参考方案2】:

似乎 PHP 能够扩展任一格式以在几乎所有情况下引用正确的值。

我能找到的唯一区别是访问对象属性时,例如

$foo = (object) ['a' => 'bar'];
echo "$foo->abar"; // barbar
echo "$foo->abar"; // Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR)

因此,考虑到这一点,我会避免使用$...

有关 PHP 字符串的更多参考资料,另请参阅 Curly braces in string in PHP。

【讨论】:

"$..." 不是支撑插值的语法,而只是"$..."。这是一个间接变量名引用。有关更多详细信息,请参阅我的答案。性能较低的原因是动态引用的开销。 这很好,但只是经验证据。我正在寻找一些确凿的事实或解释来证明它是否安全。我不想在遥远的将来发现我使用的语法已被弃用或滥用。

以上是关于在字符串内的美元符号后使用花括号是不是错误的主要内容,如果未能解决你的问题,请参考以下文章

带 f 字符串的花括号 - ValueError:字符串格式说明符中不允许符号 [重复]

ActiveAdmin剥离花括号内的内容

在 Jersey Client 2 中编码花括号

正则表达式用于选择花括号内的双引号而忽略外部的引号

C程序花括号嵌套层次统计(新)

浅析 Bash 中的 {花括号} | Linux 中国