PHP8.0.2中关联数组键的行为与PHP7不同吗?我是否应该将数组键括在引号中?

PHP8.0.2中关联数组键的行为与PHP7不同吗?我是否应该将数组键括在引号中?,php,Php,有人能帮我了解这里发生了什么吗? 双引号和单引号如何影响关联数组键的行为? 这种行为与PHP7不同吗?为什么 <?php // php version 8.0.2 echo "$assoc_array[key]"; // OK echo $assoc_array[key]; // error undefined constant "key" echo $asso

有人能帮我了解这里发生了什么吗?
双引号和单引号如何影响关联数组键的行为?
这种行为与PHP7不同吗?为什么

      <?php
        // php version 8.0.2
        echo "$assoc_array[key]";   // OK
        echo  $assoc_array[key];    // error undefined constant "key"
        echo  $assoc_array['key'];  // OK
        echo "$assoc_array['key']"; // error - unexpected string content ""
        // this behaviour seems inconsistent
      ?>

基于您的代码示例,我使用以下代码进行测试:

<?php

$assoc_array = ['key' => 'okay'];

echo "$assoc_array[key]";   // OK
echo  $assoc_array[key];    // error undefined constant "key"
echo  $assoc_array['key'];  // OK
#echo "$assoc_array['key']"; // error - unexpected string content ""
当我从上述代码中取消注释最后一行时,我得到如下结果:

PHP Parse error:  syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting '-' or identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in ...

然后,在a中运行上述代码时,我得到:


从这些测试中,我建议使用以下两种基本思想(对于PHP7.x.x和8.0.0):

  • 处理数组名称[key](不带外引号)时,使用以下格式似乎比较安全:
    $array\u name['key']
  • 在处理“array_name[key]”(在外引号中)时,使用以下格式似乎比较安全:
    “{$array_name['key']}”

希望在回答部分问题时,出现“未定义常量键”错误是因为PHP7.2.34和PHP8.0.0之间发生了更改

发生“意外字符串内容”错误的原因是,我认为需要在外部双引号字符串中使用带单引号的键的数组周围使用大括号
{…}
,才能使其正常工作。在PHP7.2.34和PHP8.0.0中,这种特殊的行为似乎相似

例如,如果您尝试使用外部单引号而不是双引号,如下所示:

echo '{$assoc_array["key"]}';
在PHP 7.2.34和PHP 8.0.0中,结果应该是:

{$assoc_array["key"]}

这并不是您想要的(它似乎正在打印字符串的文本版本)。因此,我仍然建议使用
“{$array\u name['key']}”
格式

echo  $assoc_array[key];
任何
字符串
前面没有特定字符(例如
$|->
)、以特定字符(例如
)或引号内(或
herdeoc
等)结尾的内容都假定为常量

这意味着
key
通常被认为是一个常量。但是你还没有为
key
设置一个常量值,因此PHP必须对它做些什么

在PHP8.x之前,这意味着假设它应该是一个字符串,然后再次尝试查找;这将生成一个
警告

这种行为在PHP8.x中发生了变化,现在它抛出了一个
错误
。如果不进行处理,脚本将结束

echo "$assoc_array[key]";
在本例中,
被括在引号中,因此被视为字符串。可以说,我建议这也应该抛出一个错误;它看起来更一致

然而,PHP7和PHP8中的行为是相同的

echo  $assoc_array['key'];
这只是访问关联数组的标准方法;单引号或双引号都可以。同样,这种行为在PHP版本中是一致的

echo "$assoc_array['key']";
这个有点棘手。归根结底,使用双引号和变量是一件棘手的事情。PHP必须尝试确定哪些部分是字面意思,哪些部分是标识符,而当前的过程是不允许在键周围加引号

这在PHP版本中是一致的

echo "$assoc_array['key']";

实际上,PHP提供了两种在双引号内定义变量的方法:

简单

这意味着前面有一个
$
的变量。该变量的用法如下:

echo "$variable";
echo "$array[key]";
echo "{$variable}";
echo "${variable}
echo "{$array['key']}";
echo "${array['key']}";
echo "{$array["key"]}";
echo "${array["key"]}";
echo "{$object->property}";
复杂

这意味着您几乎可以在PHP中想到的任何变量。它的用法如下:

echo "$variable";
echo "$array[key]";
echo "{$variable}";
echo "${variable}
echo "{$array['key']}";
echo "${array['key']}";
echo "{$array["key"]}";
echo "${array["key"]}";
echo "{$object->property}";

有关向后兼容性的更多信息,请参阅
PHP7>>8
迁移手册:


N.B.关键区别在于,处理未定义常量的方式(如上所述)已从
警告更改为
错误异常

在带引号的字符串中,使用带引号的数组键。
{}
“{$assoc['key']}
或不使用
{}
并且不要引用该键(我非常喜欢带引号的键)
“$assoc[key]”
。在PHP 8之前,在双引号字符串(如
$assoc[key]
之外的未加引号的键带有警告,在7.x中已被弃用。这在8中不再允许-必须始终引用除双引号字符串之外的键。在:试图访问未定义的非限定常量。以前,非限定常量访问会导致警告,并被解释为字符串。"谢谢,这有助于澄清一些问题。我想这意味着,如果系统更新到版本8,则必须检查所有代码的合规性,以便运行时不会出错。在我的情况下,这并不意味着什么,但在企业级项目中,这将阻碍版本8的采用,不是吗?@ScottMerewetherRankin很高兴听到这一点!至于检查PHP7.x.x和8.x.x之间的代码,检查代码可能是一个好主意。我记得读过关于如何使用PHP8的书,是为一些人或项目编写的。我想,对于某些项目来说,使用PHP8将比在PHP7.1到7.2到7.3之间进行更难,等等“不,不会的。”错误总是存在的,没有人应该生成带有警告的生产代码(也没有理由发出警告)。PHP8中的关键区别在于此警告(重新定义常量)已提升为
错误
异常…@summea以澄清您的最后一点:单引号(和
nowdoc
)仅用于文字字符串打印。对于单引号和反斜杠,几乎只有
\'
\`两个特殊字符。如果要使用变量和其他特殊字符(例如
\n
),则需要使用双引号(或
herdoc`);同样,情况一直如此。所有有用的建议。谢谢。