PHP:将引用插入数组?

时间:2012-07-02 03:24:20

标签: php reference

我正试图在某一点插入数组:

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

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

4 个答案:

答案 0 :(得分:6)

快速而肮脏的答案,但请注意,不推荐使用引用调用此函数,并且可能(取决于您的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'。

我认为导致它的原因是文档说:“如果 replacement 不是一个数组,它将被一个类型转换(即(数组)$参数)。”所以发生了什么:

  • 您将&amp; $ var2作为替换传递给数组。
  • 在内部,php正在将&amp; $ var2转换为数组(&amp; $ var2)。它实际上可能正在做一些等同于$ param = array($ param)的东西,这意味着&amp; $ var2将被设置为数组(&amp; $ 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',
)

答案 1 :(得分:2)

您可能需要将最后一个参数设为数组,否则根据manual,您将得到一个数组。

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

答案 2 :(得分:1)

当我尝试像你这样的例子时,我收到一条警告,上面写着“呼叫时间传递参考已被弃用”。根据{{​​3}}:

  

您可以在php.ini文件中将allow_call_time_pass_reference设置为true。但这是一个黑客攻击。

答案 3 :(得分:0)

这里我正在迭代一个数组($ values_arr)并将每个变量的引用存储在另一个数组中($ params)。您可以根据自己的要求更改其使用情况。

$params = array();
$values_arr = array('a', 'b', 123);
foreach ($values_arr as $key=>&$val) {
    $params[$key] = &$val;
}

结果

array (size=3)
  0 => &string 'a' (length=1)
  1 => &string 'b' (length=1)
  2 => &int 123