2013-03-08 5 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 

그것은 루프 후 올바른 값을 반환에 반환 것입니다 (I 디버깅에 대한 몇 가지 에코 문을 추가 한) ConnorAtherton2 수있는 기능입니다)로 시작하지만 왜 루프 뒤에 두 번째 값이 있을지 모르겠다.

ConnorAtherton1을 반환하고 ConnorAtherton2를 반환해야합니다.

도움을 주시면 대단히 감사하겠습니다.

+1

아마 당신이 찾고있는 대답은 아니지만,'WHERE username LIKE "ConnorAtherton %"'을 사용하고 마지막 숫자를 부분 문자열로 바꾸고 1을 더하기 위해 SQL을 변경하는 것에 대해 생각할 것입니다. – 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() 메소드 만 구현하면됩니다. DB 쿼리를 수행하고 이름이 이미있는 경우 true을 반환합니다.

($counter++) 부분이 첫번째 반복에 빈 문자열을 추가한다 (++ 접미사 값을 평가 하였다 후 변수를 증가시킨다).

+0

안녕하세요, Michael, 재귀없이 완료 할 수 있으며 솔루션이 훌륭하게 작동한다는 점에 동의합니다. 나는 재귀가 어떻게 작동하는지 더 잘 이해할 수 있도록이 프로그래밍 시나리오를 만들었다. –

+0

나는 본다. 그러나 가능한 한 재귀 호출을 피해야한다는 것을 명심하십시오. 이들은 일반적으로 단순한 루프보다 훨씬 비쌉니다. –

+0

@Michael - 담요 진술로 나는 당신에게 동의 할 수 없다. 언어와 작업에 따라 다릅니다. 이 경우 네, 잔인한 부분이지만 재귀가 실제로 가능합니다! –

관련 문제