2

クラスで関数を作成してユーザー名を作成したい場合、関数はユーザー名が存在するかどうかを確認し、username_1 のようにユーザー名をインクリメントします。このユーザー名が存在するかどうかを確認し、存在する場合は、新しいユーザー名が作成されるまで、username_2 にインクリメントします。この関数を作成しましたが、何も返されません。コードの何が問題なのか教えてください。

class a{

function check_username($username){


  if($usernameexist){

    return true;
  }
  else
  {

   return false;

  }

}

function create_username($username) {

        $__name = __FUNCTION__;

        if ($this->check_username($username)) {                
            $n++;
            $username = $username . "_" . $n;
            //return $__name($username);  this return fatal error.
            return call_user_func('create_username', $username);

        } else {
            return $username;               
        }
    }
}
4

3 に答える 3

3

これには再帰を使用する必要はありません。単純なwhile(){}ループで実行できます。

Plain-Jane Interator メソッド

// your original function
function create_username($username){
  // check if the username (as-is) already exists
  if ($this->check_username($username)){
    // use $n to keep a counter
    $n = 1;
    // while {username}_{n} exists, keep incrementing the counter
    while ($this->check_username($username.'_'.$n)){
      $n++;

      /* If you don't want this to check to infinity, uncomment
       * the below portion. the 100 is an arbitrary number, but use
       * whatever you want as a limitation (could even make it a
       * parameter in the method). Also, returning FALSE allows you to
       * gracefully catch when max attempts are reached.
       *
       * e.g.
       *   if (($new_user = $obj->create_username('BradChristie')) !== FALSE){
       *     // user was successfully created within the max allowed attempts
       *   }
       */
      //if ($n > 100) return FALSE
    }
    // return the result
    return $username.'_'.$n;
  }
  // username was fine, return it back
  return $username;
}

再帰的方法

// recursive username check
public function create_username($username, $n = 0)
{
  /* Same as above function, this is a check to prevent counting
   * to infinity. uncomment to apply it
   */
  //if ($n > 100) return FALSE;

  // establish the username we're testing. if $n is 0,
  // it's the original call to the function (don't add _0)
  // if it's >0, it's part of the search so include it
  $_username = $username . ($n > 0 ? '_'.$n : '');

  // check if the username exists.
  if ($this->check_username($_username))
  {
    // it exists, so make a call to this same function passing
    // the original username and the value of n + 1 (move to next
    // possibility)
    return $this->create_username($username, $n+1);
  }

  // the name, as-is, was fine. return it
  return $_username;
}

于 2013-01-16T13:30:14.943 に答える
0

この場合、再帰性は必要ありません...単純なループは完璧に機能します:

function create_username($username) {

    $original_username = $username;
    $i=1;
    while(! $this->check_username($username) ) {
        $username = $original_username . '_' .$i++;
    }

    return $username;
}
于 2013-01-16T13:26:36.797 に答える
0

コードはいくつかの点で間違っており、他の場所で指摘されているように、目的の関数は反復的に作成する方が適切です。

コードの問題のいくつかは次のとおりです。

  1. check_usernameが成功したときに再帰チェックを行っています。したがって、オリジナルを見つけられ$usernameなかった場合は、それを変更したことにはならないため、変更された値を確認することはありません。
  2. に渡された名前をcreate_username追加して変更してい_nます(適切な 用n)。再帰呼び出しで変更された名前を渡しているため、実際_nには名前に複数の部分が含まれることになります。
  3. 再帰呼び出しを制限していないため、これが正しく記述されていたとしても、最終的にネストが深くなりすぎます。
于 2013-01-16T13:35:20.283 に答える