2013-03-08 2 views
0

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

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

Например, если ConnorAtherton был взят, функция будет следующей проверкой ConnorAtherton1, ConnorAtherton2, пока не найдет уникальное имя пользователя.

Вот функция (я добавил некоторое эхо заявления для отладки)

function createUserName($username, $counter){ 

     global $fname, $lname; 

     echo "\t\t\tUsername at Start - " . $username . "\n"; 

     // connect to database 
     require($_SERVER['DOCUMENT_ROOT'] . "/inc/db.connect.php"); 

     $stmt = $conn->prepare('SELECT * FROM users WHERE username = ?'); 
     $stmt->bind_param('s', $username); 
     $stmt->execute(); 
     $stmt->store_result(); 

     echo "\t\t\tUsername before loop - " . $username . "\n"; 

      if($stmt->num_rows > 0){ 

       //construct original name and try again 
       $username = ucfirst($fname) . ucfirst($lname) . $counter; 
       $counter++; 
       createUserName($username, $counter); 

      } 

      echo "\t\t\tUsername after loop - " . $username . "\n\n"; 

      return $username; 
    } 

Вот что он возвращается к консоли

Username at Start - ConnorAtherton 
    Username before loop - ConnorAtherton 
    Username at Start - ConnorAtherton1 
    Username before loop - ConnorAtherton1 
    Username at Start - ConnorAtherton2 
    Username before loop - ConnorAtherton2 
    Username after loop - ConnorAtherton2 

    Username after loop - ConnorAtherton1 

возвращает правильное значение после цикла (ConnorAtherton2), но я не знаю, почему после цикла будет второе значение.

Он возвращает ConnorAtherton1, и мне нужно его, чтобы вернуть ConnorAtherton2.

Любая помощь очень ценится.

+1

Возможно, это не тот ответ, который вы ищете, но я бы подумал об изменении вашего sql, чтобы использовать 'WHERE username LIKE" ConnorAtherton% "', а затем подставляя последнюю цифру (цифры) и добавляя 1 :) – Julien

ответ

3

Код исполняется, как ожидалось. То, что вы видите, - это просто стоп, который освобождается от рекурсивных вызовов.

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

 //... 
    $counter++; 
    return createUserName($username, $counter); 
} 
//... Rest of fn omitted 
+0

Спасибо, отлично работает :) Я обязательно узнаю в следующий раз –

+0

Отлично. Я рад, что смогу помочь! В соответствующей заметке, как указывали другие, вы можете достичь того же без рекурсии, но понимание рекурсивных функций всегда может пригодиться;) –

1

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

$counter = ''; 
do { 
    $username = ucfirst($fname) . ucfirst($lname) . ($counter++); 
} while(!doesNameExist($username)); 

Вы бы только реализовать метод doesNameExist(). Там вы делаете запрос БД и возвращаете true, если имя уже существует.

($counter++) часть будет добавить пустую строку на первой итерации (суффикс ++ увеличивает переменную после значение оценивали).

+0

Эй, Майкл, я согласен с вами в том, что это можно сделать без рекурсии, и ваше решение отлично работает. Я создал этот сценарий программирования, чтобы лучше понять, как работает рекурсия :) –

+0

Я вижу. Но имейте в виду, что вам следует избегать рекурсивных вызовов, если это возможно - они обычно намного дороже, чем простой цикл. –

+0

@ Майкл - в качестве основного заявления Я не могу согласиться с тобой. Это зависит от языка и задачи. В этом случае да, это слишком много, но в других случаях рекурсия может быть действительно замечательной! –

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