2012-07-02 64 views
7

我试图插入到一个数组中某一点:PHP:插入参考到数组中?

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

为什么试图将其插入到与拼接数组失败,使用第一种方法没有?

回答

6

快速和肮脏的答案,但请注意,调用与参考此功能已过时,并且可能(取决于你的PHP配置)发出警示:

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

的hows-然后回答:发生的事情非常微妙。当你进行拼接时,因为你已经在该位置插入了一个引用,$ 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是一个字符串,就像你希望它是( '下一个')。但在拼接之后,$ var2已被包含一个元素的数组替换,字符串为'next'。

我认为是什么导致它是什么文档说:“如果替代不是一个数组,它将被转换为一个(即(数组))。”所以发生是这样的:

  • 你传递& $ VAR2成数组作为更换
  • 在内部,php正在将& $ var2转换为数组(& $ var2)。它可能实际上做的是相当于$ param = array($ param)的东西,这意味着& $ var2将被设置为数组(& $ 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', 
) 
+0

P.S.我认为使用数组(&$ var2)调用它的原因是因为在内部,splice不需要通过自赋值将&$ var2转换为数组(&$ var2),从而在进程中更改$ var2 。你明确地创建了一个新的符号数组(&$ var2),它在内存中是物理分离的,不需要自赋值。 –

+0

P.P.S.这种意想不到的副作用正是为什么呼叫时间通过引用已被弃用。 ;) –

+0

@AndyLobel你应该改变这个接受的答案。 – Hamish

2

您可能需要将最后一个参数作为数组,否则根据manual,您会将其指定为一个。

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

tehe做得好;) –

+0

解决方案是正确的,但对于@ Travesty3的原因。类型转换不是一个问题 - 通过引用的通话时间失败。 – Hamish

+0

from the manual:'如果替换只是一个元素,则不需要在它周围放置array(),除非该元素是一个数组本身,一个对象或NULL。“ – alfasin

1

当我试图像你这样一个例子,我得到的说,一个警告“在调用的时候传递通过引用已被弃用。”根据this answer

你可以在你的php.ini文件中设置allow_call_time_pass_reference为true。但这是一个破解。

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