Можете ли вы сделать рекурсивную функцию PHP без повторения ее имени?
Мне всегда приходилось записывать рекурсивную функцию, чтобы назвать себя, когда экземпляр класса может использовать $this
, а статический метод может использовать self
и т.д.
Есть ли аналогичный способ сделать это в рекурсивной функции, не называя ее снова (просто для сокращения обслуживания)?
Очевидно, я мог бы использовать константу call_user_func
или __FUNCTION__
, но я предпочел бы что-то менее уродливое.
Ответы
Ответ 1
Вы можете использовать переменные функции и объявить переменную с именем функции в начале (или где угодно). Нет необходимости в call_user_func
:
function test($i) {
$__name = __FUNCTION__;
if($i > 5) {
echo $i. "\n";
$__name($i-1);
}
}
Не забывайте, что использование имени реальной функции, вероятно, более читаемо для других людей:)
(по крайней мере, дайте комментарий, почему вы это делаете)
Обновление:
Как упоминает @Alix в своем комментарии, может быть полезно объявить $__name
как static
. Таким образом, значение не присваивается снова и снова переменной.
Ответ 2
Я не знаю, почему это уродливо:
return call_user_func_array(__FUNCTION__, func_get_args());
Versus:
return call_user_func_array('someFunction', func_get_args());
Вам все равно нужно использовать call_user_func_array()
, если вы хотите сократить обслуживание (если ваши функции имеют [много/другое число] аргументов).
Кроме этого Я не вижу другого пути. Также статический метод не может ссылаться сам, используя self::
, только на свой класс. Для этого вам также понадобится использовать магическую константу __METHOD__
.
Ответ 3
function anyfunc() {
__FUNCTION__();
}
если используется в классе:
protected function anymethod() {
$this->{__FUNCTION__}();
}
Ответ 4
Для тех из вас, кто хочет сделать это в статическом методе:
forward_static_call(array('self', __METHOD__), $arg1, $arg2, $etc);
Таким образом, если метод переименован, вам также не придется беспокоиться об изменении всех вызовов рекурсии внутри него.
Ответ 5
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);