2011-05-26 49 views
10

用於PHP是可能的以下模式:PHP數組,並通過按引用

$arr = array(1, 2, 3); 
$newarr = foo($arr); 

或pass-:

function foo($arr) 
{ 
    // modify $arr in some way 
    return $arr; 
} 

這可以隨後使用通過噪聲值被稱爲通過參考:

$arr = array(1, 2, 3); 
foo(&$arr); 

但「呼叫時傳遞引用已被棄用」。修改函數簽名:

function foo(&$arr) 

將處理傳遞按引用的情況下,反而會打破原有功能的兩用性質,因爲傳遞的價值已不再可能。

有沒有辦法解決這個問題?

+0

它觸發一個E_DEPRECATED,它只是一個* notice *錯誤級別。但功能本身不受影響。這不是「不再可能」。 (它仍然不會被刪除在明年的PHP 5.4 ..) – mario 2011-05-26 12:35:54

+0

我的意思是通過價值傳遞時調用一個函數聲明爲通過引用參數是不可能的。正如你所指出的那樣,即使函數沒有以這種方式聲明它的參數,它仍然是可能的*,但我總是希望儘可能避免被棄用的東西。 – 2011-05-26 12:41:40

+1

是的,這正是爲什麼它被*聲明*棄用。沒有太多想法,它通常被濫用。而這個錯誤信息是爲了嚇跑人們遠離這種語法。現在您已經對實際代碼進行了一些思考,它不再適用於您。 (我會避免在非即時即將被刪除的支持語法上使用繁瑣的解決方法。) – mario 2011-05-26 12:44:36

回答

5

我想,你這是接近:

function foo(&$bar) { ... } 

foo($array);    // call by reference 
$bar = foo($_tmp = $array); // call by value 

不幸的是這將需要一些改變,以每次呼叫。

+0

這可能是這裏最好的選擇;清晰可讀。 – mario 2011-05-26 13:25:32

+1

我應該注意,我不會真的推薦以這種方式編寫代碼。例如,你可以簡單地寫'$ bar = $ array; foo($ bar);'這裏的目標只是儘量模仿不贊成使用的語法。另外,如果你想改變你的代碼,請記住,使用按值傳遞的行不會產生任何警告,並且像這樣切換函數會導致它在這些情況下默默地改變行爲。就個人而言,我會繼續使用代碼,並在此期間開始尋找更好的第三方庫。 – Matthew 2011-05-26 13:32:57

2

雙重用途的本質是愚蠢的,這就是爲什麼行爲被棄用。正如你所建議的那樣修改函數簽名。

+7

雙重用途本質並不愚蠢,因爲如果通過引用傳遞變量,可以修改變量,這很危險。現在我們不得不顯式聲明變量是否被引用傳遞。它具有它的優點(不那麼謹慎的程序員不會自己動手,PHP可以最終傳遞參數而不會複製值)和缺點(沒有雙重用途,所以執行幾乎相同的事情的函數必須被聲明兩次)。 – 2011-05-26 12:46:39

+0

@Bobby:邁克爾說了些什麼。 :) – 2011-05-26 13:27:28

+0

非常好的總結,@Michael – 2011-05-26 13:58:45

1

不幸的是,我不相信有一種解決辦法。

只是讓你的功能使用&的參考。

1

簡單的解決方法是準備一個包裝函數:

function foo($arr) { 
    return foo_ref($arr); 
} 

function foo_ref(&$arr) { 
    ... 

然後根據當前的使用,無論是調用正常foo()foo_ref()如果希望陣列到位進行修改。


還有一個共同array(&$wrap)參數作弊,但似乎並不適合你的情況。一個更現代的解決方法將是這個棘手的把戲:

// pass by value 
foo($array); 

// pass by reference (implicitly due to being an object) 
foo($array = new ArrayObject($array)); 

這允許類似的參考傳遞到準備好的功能。就我個人而言,我寧願保留E_DEPRECATED警告和爲此目的的預期語法。

+2

不幸的是'ArrayObject'不能用於數組函數,所以它不一定是一個插件「修復」。否則,它可能會起作用。 – Matthew 2011-05-26 13:16:22