Can you make a PHP function recursive without repeating its name?
It's always bugged me a recursive function needs to name itself, when a instantiated class can use $this
and a static method can use self
etc.
Is there a similar way to do this in a recursive function without naming it again (just to cut down on maintenance)?
Obviously I could use call_user_func
or the __FUNCTION__
constant but I would prefer something l开发者_Go百科ess ugly.
You can make use of variable functions and declare a variable with the function name at the beginning of you function (or wherever). No need for call_user_func
:
function test($i) {
$__name = __FUNCTION__;
if($i > 5) {
echo $i. "\n";
$__name($i-1);
}
}
Don't forget that using the real function name is probably more readable for other people :)
(at least provide a comment why you do this)
Update:
As @Alix mentions in his comment, it might be useful to declare $__name
as static
. This way, the value is not assigned over and over again to the variable.
I don't know why this is ugly:
return call_user_func_array(__FUNCTION__, func_get_args());
Versus:
return call_user_func_array('someFunction', func_get_args());
You would still need to use call_user_func_array()
if you're looking to cut down on maintenance (if your functions have [a lot / a different number] of arguments).
Other than that I don't see another way. Also a static method cannot reference itself using self::
, only to its class. You would also need to use the magic __METHOD__
constant to do that.
function anyfunc() {
__FUNCTION__();
}
if used in class:
protected function anymethod() {
$this->{__FUNCTION__}();
}
For those of you who want to do this within a static method:
forward_static_call(array('self', __METHOD__), $arg1, $arg2, $etc);
This way if the method is renamed you dont have to worry about changing all the recursion calls within it too.
function self(){
return call_user_func_array(debug_backtrace()[1]['function'], func_get_args());
}
function test($i) {
if($i) {
echo "$i<br>\n";
self($i-1);
}
}
test(5);
You can simply include the arguments by combining func_get_args()
and the Variadic
or ...
added in 5.6.
As a procedural function
function foo($arg,$arg1) {
__FUNCTION__(...func_get_args());
}
As a class method:
protected function foo($arg,$arg1,$arg3, $etc) {
$this->{__FUNCTION__}(...func_get_args());
}
https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list
Coincidently this works anytime you want to inject an array of arguments into a method or function...
For example (these are also equivalent)
public function foo($arg,$arg1)
call_user_func_array([$this, __FUNCTION__], func_get_args());
}
call_user_func_array
should be Deprecated in my opinion, because there is no need for it in several ways. Most obvious to me is this.
public function foo($arg,$arg1)
call_user_func([$this, __FUNCTION__], ...func_get_args());
}
The ...
is quite useful (I think it plays well with named arguments, though I haven't tried that yet).
精彩评论