2012-12-18 3 views
2

Я пытаюсь запустить рекурсивную функцию, но она не работает должным образом. Я не вижу ошибок в моем коде, так что, возможно, это просто невозможно с PHP?Простая рекурсивная функция не работает

<?php 

$herpNum = 0; 

function herp() { 
    if ($herpNum == 22) { 
     echo "done"; 
    } else { 
     $herpNum = $herpNum+1; 
     echo $herpNum."<br/>"; 
     herp(); 
    } 
} 

herp(); 

?> 

, когда я запускаю это, результат просто длинный список 1.

+3

PHP не имеет области видимости цепей, которые работают как JavaScript. – alex

+0

http://php.net/functions.user-defined - на этой странице см. [* Пример # 4 Рекурсивные функции *] (http://php.net/functions.user-defined#example-150) для аналогичного но рабочий вариант. – hakre

+0

Также, пожалуйста, используйте поиск, прежде чем задавать вопрос. Я уверен, что QA-материал о том, как написать рекурсивную функцию в PHP, существует уже на сайте (рядом с самим руководством PHP). – hakre

ответ

4

Поскольку $ herpNum не в том же объеме, как функции, так как это создает новый $ herpNum внутри функции который по умолчанию равен 0, а затем добавляет к нему 1.

Вы можете либо передать его в качестве аргумента, либо использовать его как глобальную переменную.

$herpNum = 0; 

function herp($herpNum) { 
    if ($herpNum == 22) { 
     echo "done"; 
    } else { 
     $herpNum = $herpNum+1; 
     echo $herpNum."<br/>"; 
     herp($herpNum); 
    } 
} 

herp($herpNum); 

или

$herpNum = 0; 

function herp() { 
    global $herpNum; 

    if ($herpNum == 22) { 
     echo "done"; 
    } else { 
     $herpNum = $herpNum+1; 
     echo $herpNum."<br/>"; 
     herp(); 
    } 
} 

herp(); 
+0

взорвался, я забыл о необходимости определять переменную как глобальную. Я не создал функцию PHP через некоторое время: P –

+3

@CharlesJohnThompsonIII Однако вам действительно следует избегать использования глобальных переменных. Вместо этого используйте версию с параметром функции. – dualed

+0

Что случилось с глобалами? Единственный ответ, который я получил для этого, не имеет никакого смысла. –

2

Проблема заключается в том, что $herpNum является redefinded в качестве локального вар в рамках herp() каждый раз, когда вызывается herp(). Это приведет к циклу рекурсии до тех пор, пока не будет достигнут «максимальный уровень вложенности функции« 100 »...». (Вы можете увидеть ошибки, когда вы установите значение INI PHP «display_errors» на «On»)

Изменить код выше:

$herpNum = 0; 

function herp() { 
    global $herpNum; 
    if ($herpNum == 22) { 
     echo "done"; 
    } else { 
     $herpNum = $herpNum+1; 
     echo $herpNum."<br/>"; 
     herp(); 
    } 
} 

herp(); 

Обратите внимание, что если $herpNum используется только herp() это может быть лучше объявить его как статическую переменную внутри herp().

function herp() { 
    static $herpNum = 0; 
    // ... 

Статическое ключевое слово сообщает интерпретатору PHP, что оно должно инициализировать переменную только один раз, когда функция вызывается в первый раз. Это должно идеально соответствовать вашим потребностям проектирования;)

+0

Оба предложения неверны, для рекурсии в PHP-pass в качестве параметра. – hakre

+0

Можете ли вы объяснить, что не так с предложениями? – hek2mgl

+0

Они на самом деле не очень хорошие практики, но не ошибаются ... – dualed

3

Это потому, что вы не передаете параметр $herpnum в функцию.

<?php 

$herpNum = 0; 

function herp($herpNum) { 
    if ($herpNum == 22) { 
     echo "done"; 
    } else { 
     $herpNum = $herpNum+1; 
     echo $herpNum."<br/>"; 
     herp($herpNum); 
    } 
} 

herp($herpNum); 

?> 

Это должно работать

0

попробовать:

$herpNum = 0; 

function herp() { 
    global $herpNum; 
    if ($herpNum == 22) { 
     echo "done"; 
    } else { 
     $herpNum = $herpNum+1; 
     echo $herpNum."<br/>"; 
     herp(); 
    } 
} 
herp(); 

Но это не рекомендуется по соображениям безопасности.

Вот пример:

... 
if($admin == true) { 
    echo 'yeah! You are the admin!'; 
} 
... 

если $admin был объявлен как глобальный и не проверяется должным образом, вам просто нужно ввести http://mysite.com/?admin=true сделать тестовый проход.

Кстати ... Для рекурсии, то предпочтительнее вводить «окружающую среду» (один или несколько аргументов) в качестве параметра:

herp($herpNum=0); // if nothing is given, $herpNum is set to 0 
+0

Можете ли вы подробно остановиться на этих соображениях безопасности? Я не вижу проблем с глобальными переменными. –

+0

Я обновил ответ –

+0

, но это применимо только в том случае, если $ admin был установлен через $ admin = $ _GET ['admin'] ;, не так ли? –

Смежные вопросы