我试图在某个点插入到一个数组中:

$hi = "test";
$var2 = "next";
$arr = array(&$hi);
$arr[] = &$var2; // this works
array_splice($arr, 1, 0, &$var2); // this doesn't

为什么尝试使用 splice 将其插入数组会失败而使用第一种方法却不会?

最佳答案

快速而肮脏的答案,但请注意,不推荐使用引用调用此函数,并且可能(取决于您的 php 配置)生成警告:

array_splice($arr, 1, 0, array(&$var2));

如何回答:正在发生的事情非常微妙。当你进行拼接时,因为你已经在那个位置插入了一个引用, $var2 实际上被重新分配了。您可以使用以下代码进行验证:
<?php
  $hi = "test";
  $var2 = "next";
  $arr = array(&$hi);
  $arr[] = &$var2; // this works
  printf("=== var2 before splice:\n%s\n", var_export($var2, TRUE));
  array_splice($arr, 1, 0, &$var2); // this doesn't
  printf("=== var2 after splice:\n%s\n", var_export($var2, TRUE));
?>

您将得到以下结果:
=== var2 before splice:
'next'
=== var2 after splice:
array (
  0 => 'next',
)

请注意,在拼接之前,$var2 是一个字符串,正如您所期望的那样 ('next')。但是,在拼接之后,$var2 已被替换为包含一个元素的数组,即字符串 'next'。

我认为导致它的原因是文档所说的:“如果替换不是数组,它将被类型转换为一个(即(数组)$parameter)。”所以发生的事情是这样的:
  • 您将 &$var2 作为替换传递到数组中。
  • 在内部,php 正在将 &$var2 转换为 array(&$var2)。它实际上可能正在做一些等同于 $param = array($param) 的事情,这意味着 &$var2 将被设置为 array(&$var2),并且因为它是一个引用而不是像通常那样的 $var2 的副本会,这会影响通常超出调用范围的变量。
  • 现在它将 $var2 的这个新值移动到结束位置,并在第二个位置插入 $var2 的副本。

  • 我不确定内部发生的事情的所有神奇之处,但在拼接期间肯定会重新分配 $var 。请注意,如果您使用第三个变量,因为它不会将某些内容分配给已作为引用存在的内容,因此它会按预期工作:
    <?php
      $hi = "test";
      $var2 = "next";
      $var3 = "last";
      $arr = array(&$hi);
      $arr[] = &$var2; // this works
      array_splice($arr, 1, 0, &$var3);
      printf("=== arr is now\n%s\n", var_export($arr, TRUE));
    ?>
    

    生成结果:
    === arr is now
    array (
      0 => 'test',
      1 => 'last',
      2 => 'next',
    )
    

    关于PHP:将引用插入数组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11287471/

    10-13 02:47