Подтвердить что ты не робот

Можете ли вы сделать рекурсивную функцию PHP без повторения ее имени?

Мне всегда приходилось записывать рекурсивную функцию, чтобы назвать себя, когда экземпляр класса может использовать $this, а статический метод может использовать self и т.д.

Есть ли аналогичный способ сделать это в рекурсивной функции, не называя ее снова (просто для сокращения обслуживания)?

Очевидно, я мог бы использовать константу call_user_func или __FUNCTION__, но я предпочел бы что-то менее уродливое.

4b9b3361

Ответ 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);