“usort”中的排序函数在PHP中被“唤醒”了吗? 致命错误:无法重新声明功能?
Recently stumbled upon this neat little bug or 'feature' in 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);
}
Results in a fatal error "cannot redeclare function inner in ...", when called like this
usort($myArray, 'myCmpFunc');
It works flawlessly when function inner is declared outside of myCmpFunc and/or $myArray has not more than 2 elements ;)
-- edit --
somehow Related: PHP Fatal error: Cannot redeclare function
So here is my question, then: Is it possible to declare functions in local scope?
-- edit 2 --
Maybe, this works well in PHP 5.3 just read it has closures, yeehaa!
最近在PHP中发现了这个整洁的小 导致致命错误 strong>“无法重新声明内部函数...”,当这样调用时 p>
当函数 inner em>在之外声明时,它可以完美运行 myCmpFunc em>
and /或 $ myArray em>不超过2个元素;) p>
- 编辑 - p>
以某种方式相关:
PHP致命错误:无法重新声明功能
所以这是我的问题,然后:
是否可以声明函数 本地 em>范围? p>
- 编辑2 - p>
也许,这在PHP 5.3中运行良好只是读它有 闭合,yeehaa! p>
div> bug或 strike>'功能': p >
function myCmpFunc($ a,$ b){
function inner($ p){
//做某事
}
$ inner_a = inner($ a);
$ inner_b = inner($ b);
if($ inner_a == $ inner_b)返回0;
return($ inner_a> $ inner_b?-1:1);
}
code > pre>
usort($ myArray,'myCmpFunc');
code> pre>
function inner($p)
is defined each time that function myCmpFunc($a,$b)
is executed. Furthermore, the inner function is visible outside function myCmpFunc($a,$b)
after that (which pretty much takes the sense out of allowing nested function definitions). That's why you get a duplicate definition error when you call the outer function a second time.
To work around this, check whether function_exists
in the body of function myCmpFunc($a,$b)
.
The function declaration is inside myCmpFunc
, and because usort
would call myCmpFunc
for each element of an array, what happens is similar to declaring a function N times.
The issue is you must call the outer function before using the inner function. As per this answer to a similar question Can I include a function inside of another function?
So your use of inner($a);
is not valid.
As of PHP v5.3 one can now write it the nice way:
$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);