2011-05-10 19 views
1

最近偶然發現了在PHP這個整潔的小 錯誤或 「功能」:在'usort'中排序函數在PHP中「逃避」?致命錯誤:無法重新聲明函數?

function myCmpFunc($a,$b) { 
    function inner($p) { 
     // do something 
    } 
    $inner_a = inner($a); 
    $inner_b = inner($b); 
    if ($inner_a == $inner_b) return 0; 
    return ($inner_a > $inner_b ? -1 : 1); 
} 

導致致命錯誤「不能重新聲明函數...內」,當這樣調用

usort($myArray, 'myCmpFunc'); 

它完美的作品時功能之外聲明myCmpFunc 和/或$ myArray的有不超過2元;)

- 編輯 -

某種聯繫: PHP Fatal error: Cannot redeclare function

因此,這裏是我的問題,然後: 是否有可能在聲明功能本地範圍?

- 編輯2 -

也許,這非常適用於PHP 5.3剛纔讀它關閉,yeehaa!

+0

這是個問題嗎? – 2011-05-10 15:11:14

+2

編寫代碼*編譯*但是*無效*不構成PHP *錯誤*。 – 2011-05-10 15:13:21

+0

@ jason-mccreary你是對的。儘管如此,我發現在函數中聲明函數並將它們放在外函數的局部範圍內是很有用的。 不在PHP中,因爲函數總是在全局範圍內,我學會了。然後必須使用方法。 – 2011-05-11 06:29:45

回答

2

function inner($p)每當執行function myCmpFunc($a,$b)時被定義。此外,內部函數在function myCmpFunc($a,$b)之後可見(這幾乎意味着允許嵌套函數定義)。這就是爲什麼當你第二次調用外部函數時會出現重複的定義錯誤。

要解決此問題,請檢查function myCmpFunc($a,$b)正文中的function_exists

+0

你一定是對的,那個函數總是被**添加到全局範圍中。 – 2011-05-10 15:24:32

1

函數聲明是內部myCmpFunc,並且因爲usort稱之爲myCmpFunc用於陣列中的每個元素,會發生什麼情況類似於聲明一個函數N次。

1

問題是您必須在使用內部函數之前調用外部函數。根據對類似問題的回答Can I include a function inside of another function?

因此您使用inner($a);無效。

+0

myCmpFunc在內部調用之前被調用... – 2011-05-10 15:21:14

+0

@ line-o,不在myCmpFunc的主體內 – Jordan 2011-05-10 15:24:29

+0

這隻適用於在條件內聲明的函數。 – 2011-05-11 06:35:17

0

由於PHP V5.3的一個現在可以把它寫的很好的方式:

$myCmpFunc = function ($a, $b) { 
    static $inner = function ($element) { 
     return $element['width']; // just as an example 
    }; 
    $inner_a = $inner($a); 
    $inner_b = $inner($b); 
    if ($inner_a == $inner_b) return 0; 
    return ($inner_a > $inner_b ? -1 : 1); 
}; 
usort($anArray, $myCmpFunc); 
相關問題