【问题标题】:Is it wrong to use curly braces after the dollar sign inside strings在字符串内的美元符号后使用花括号是否错误
【发布时间】:2025-12-19 20:15:16
【问题描述】:

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

$foo = 'bar';
$bar = "${foo}bar is allowed"; //or
$bar = "{$foo}bar 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

标签: 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]" 有效,但 "$array{key}""$array{'key'}" 都无效.

结论

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

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

另见 PHP 文档:

(区分)

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

  • Accessing array elements

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

【讨论】:

  • 你是说$bar['ba'.'z'] 等价于$bar{'ba'.'z'}?因为"$bar[baz]" 不等于"$bar{baz}"。 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->a}bar"; // barbar
echo "${foo->a}bar"; // Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR)

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

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

【讨论】:

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