【问题标题】:Why does this syntax work to parse an associative array value into a string?为什么此语法可以将关联数组值解析为字符串?
【发布时间】:2014-12-15 21:18:59
【问题描述】:

我正在学习 codeacademy.com 上的 PHP 课程,Advanced Arrays 的第 4/7 课想要编写一个 echo 语句来访问关联数组中的值。

我的第一次尝试是:

echo "I own a $myAssocArray['colour'] $myAssocArray['doors']-door $myAssocArray['year'] $myAssocArray['make'].";

引发错误:

解析错误:语法错误,意外的 T_ENCAPSED_AND_WHITESPACE,预计第 26 行有 T_STRING 或 T_VARIABLE 或 T_NUM_STRING

我意识到我可以使用连接运算符来做到这一点:

echo "I own a " . $myAssocArray['colour'] . " " . $myAssocArray['doors'] . "-door " . $myAssocArray['year'] . " " . $myAssocArray['make'] . ".";

在玩的时候,我只需删除数组访问器中的撇号就可以实现这一点。下面的编译没有错误并产生预期的字符串:

echo "I own a $myAssocArray[colour] $myAssocArray[doors]-door $myAssocArray[year] $myAssocArray[make].";

我还可以使用花括号表示法以我认为需要的方式访问数组值:

echo "I own a {$myAssocArray['colour']} {$myAssocArray['doors']}-door {$myAssocArray['year']} {$myAssocArray['make']}.";

我的理解是关联数组值可以通过索引(整数)或键(字符串)访问。

  1. 我的理解有误吗?
  2. 还是有一些我没有掌握的基本原则?
  3. 或者这是 codeacademy.com 使用的 PHP 编译器特有的行为?

如何才能准确解析这种语法?

echo "some text $associative_array[key] some more text";

编译器如何知道将key(或colourdoorsmakeyear 等)解释为字符串值?

【问题讨论】:

  • 1.你的理解是正确的。 2. 没有。 3. 这是 PHP 的行为。很奇怪,对吧? 4.见3
  • 通常,如果您这样做,那么大多数人更喜欢使用大括号表示法。虽然大多数理智的人可能会使用printf|sprintfstrtr...
  • 从 C 迁移的人至少会使用 printf,但是如果您从 C 迁移到 PHP,我不确定“理智”一词是否适用于您。 ;)
  • 哈......如果你想进入 Web 开发,那就不要了。显然,还有其他语言可能会被许多人认为更好,或者至少有比 PHP 更可接受的缺点列表,但是一旦你习惯了它,它就不错了。然而,有很多缺乏纪律的开发人员在使用它哈哈,我觉得这也是它获得如此糟糕代表的部分原因。

标签: php


【解决方案1】:

PHP 就是这样,一致性是一种致命的罪过:

  • 不能引用双引号字符串中的数组键,除非它们在 {} 嵌入语法中。
  • 双引号字符串中的多维数组/对象以非贪婪的方式进行解析,这就是{} 扩展字符串语法的原因。

考虑:

$foo['bar']['baz'] = 'qux'; // a simple 2 layer array

显而易见的:

echo "Hello, $foo['bar']['baz']" // error: t_encapsed_and_whitespace

快速修复,删除引号:

echo "Hello, $foo[bar][baz]" // outputs: Hello, Array[baz]

实际上被解析/执行为:

echo "Hello, ";    // plain string
echo $foo['bar'];  // array in string context, which will print as the word "Array"
echo "[baz]";      // Another plain string

由于 PHP 的解析器不是贪婪的,它在 FIRST ] 之后停止,认为这是数组的结尾。所以你的“上层”数组被转换为字符串,产生字面量Array,而其余的数组键业务则被视为纯文本。

输入扩展语法:

echo "Hello, {$foo['bar']['baz']}"; // Outputs: Hello, qux

{} 用于分隔整个数组/对象引用,强制 PHP 将所有 [] 块视为键。而且由于您现在处于特殊的“array-/object-in-string”模式,因此必须再次引用数组键。

对于对象,也会发生同样的事情:

$foo->bar->baz = 'qux'; 
echo "Hello, $foo->bar->baz";

然后导致“stdclass 的对象无法转换为字符串”,因为它被解析/执行为:

echo "Hello, ";
echo $foo->bar;
echo "->baz"; 

除非bar 子对象实现了神奇的__toString() 方法,否则会出现“无法转换”的错误。但无论如何,加上{} 符号就可以了”

echo "Hello, {$foo->bar->baz}"; // outputs: Hello, qux

【讨论】:

    猜你喜欢
    • 2022-01-05
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 2013-06-09
    • 2017-02-02
    相关资源
    最近更新 更多