2012-07-02 84 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