PHP数组索引:$ array [$ index] vs $ array [" $ index"] vs $ array [" {$ index}"]

时间:2020-03-05 18:38:44  来源:igfitidea点击:

这些索引到PHP数组的方法之间有什么区别(如果有):

$array[$index]
$array["$index"]
$array["{$index}"]

我对性能和功能上的差异都感兴趣。

更新:

(响应@Jeremy)我不确定这是正确的。我运行了这段代码:

$array = array(100, 200, 300);
  print_r($array);
  $idx = 0;
  $array[$idx] = 123;
  print_r($array);
  $array["$idx"] = 456;
  print_r($array);
  $array["{$idx}"] = 789;
  print_r($array);

并得到以下输出:

Array
(
    [0] => 100
    [1] => 200
    [2] => 300
)

Array
(
    [0] => 123
    [1] => 200
    [2] => 300
)

Array
(
    [0] => 456
    [1] => 200
    [2] => 300
)

Array
(
    [0] => 789
    [1] => 200
    [2] => 300
)

解决方案

回答

如果$ index是字符串,则没有区别,因为$ index," $ index"和" {$ index}"的求值都是相同的字符串。如果$ index是一个数字,例如10,则第一行将评估为$ array [10],其他两行将评估为$ array [" 10"],该元素与$ array [10]不同。

回答

我相信从性能角度来看,$ array [" $ index"]比$ array [$ index]更快,请参见优化PHP代码性能的最佳实践。

当我在字符串中有数组时,有时会使用的另一种变化是:

$str = "this is my string {$array["$index"]}";

编辑:我的意思是说$ row [id]比$ row [id]快

回答

对更新的回应:

哦,我们是对的,我猜PHP如果只包含数字,则必须将数组索引字符串转换为数字。我尝试了这段代码:

$array = array('1' => 100, '2' => 200, 1 => 300, 2 => 400);
print_r($array);

输出为:

Array([1] => 300 [2] => 400)

我进行了更多测试,发现如果数组索引(或者键)仅由数字组成,则始终将其转换为整数,否则为字符串。

垃圾桶:

我们能解释一下为什么这样更快吗?解释器是否需要采取额外的步骤,才能将" $ index"解析为字符串以用作索引,而不仅仅是将$ index用作索引?

回答

参见上面的@svec和@jeremy。所有数组索引都首先是'int'类型,然后是'string'类型,并将在PHP认为合适的情况下强制转换为该类型。

在性能方面,$ index应该比" $ index"和" {$ index}"(相同)要快。

一旦启动了双引号字符串,PHP将进入插值模式,并首先将其视为字符串,但会在本地范围内寻找要替换的变量标记($,{}等)。这就是为什么在大多数讨论中,除非需要" \ n"或者" \ t"之类的转义快捷键,否则真正的"静态"字符串应始终为单引号,因为PHP无需在运行时尝试对字符串进行插值,而完整的字符串可以静态编译。

在这种情况下,双引号将首先将$ index复制到该字符串中,然后返回该字符串,而直接使用$ index将仅返回该字符串。

回答

我对使用索引的3种方式进行了计时,如下所示:

for ($ii = 0; $ii < 1000000; $ii++) {
   // TEST 1
   $array[$idx] = $ii;
   // TEST 2
   $array["$idx"] = $ii;
   // TEST 3
   $array["{$idx}"] = $ii;
}

第一组测试使用$ idx = 0',第二组使用$ idx =" 0",第三组使用$ idx =" blah"。使用microtime()diffs来完成计时。我正在使用WinXP,PHP 5.2,Apache 2.2和Vim。 :-)

结果如下:

使用$ idx = 0

$array[$idx]            // time: 0.45435905456543 seconds
$array["$idx"]          // time: 1.0537171363831 seconds
$array["{$idx}"]        // time: 1.0621709823608 seconds
ratio "$idx" / $idx     // 2.3191287282497
ratio "{$idx}" / $idx   // 2.3377348193858

使用$ idx =" 0"

$array[$idx]            // time: 0.5107250213623 seconds
$array["$idx"]          // time: 0.77445602416992 seconds
$array["{$idx}"]        // time: 0.77329802513123 seconds
ratio "$idx" / $idx     // = 1.5163855142717
ratio "{$idx}" / $idx   // = 1.5141181512285

使用$ idx =" blah"

$array[$idx]           // time: 0.48077392578125 seconds
$array["$idx"]         // time: 0.73676419258118 seconds
$array["{$idx}"]       // time: 0.71499705314636 seconds
ratio "$idx" / $idx    // = 1.5324545551923
ratio "{$idx}" / $idx  // = 1.4871793473086

因此,$ array [$ idx]是性能竞赛的不二之选,至少在我的机器上是如此。 (结果是非常可重复的,顺便说一句,我运行了3到4次,得到了相同的结果。)

回答

When will the different indexing methods resolve to different indices?

根据http://php.net/types.array,数组索引只能是整数或者字符串。如果尝试将float用作索引,它将把它截断为整数。因此,如果$ index是值为3.14的浮点数,则$ array [$ index]的计算结果为$ array [3]和$ array [" $ index"]的计算结果为$ array ['3.14']`。这是一些确认这一点的代码:

$array = array(3.14 => 'float', '3.14' => 'string');
print_r($array);

$index = 3.14;
echo $array[$index]."\n";
echo $array["$index"]."\n";

输出:

Array([3] => float [3.14] => string)
float
string

回答

I believe from a performance
  perspective that $array["$index"] is
  faster than $array[$index] See Best
  practices to optimize PHP code
  performance

不要相信我们盲目阅读的所有内容……我认为我们误解了这一点。文章说$ array ['index']比$ array [index]快,在$ array [index]中,index是一个字符串,而不是一个变量。那是因为如果我们不将其用引号引起来,PHP会寻找一个常量var,并且找不到一个常量var,因此假设我们打算将其设为字符串。