2

ランダムな文字列を生成する次の関数があります。

public function generateString(){
    function generateCharacter () {
        $possible = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
        return $char;
    }
    function generateNumber () {
        $GUID = generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter().generateCharacter();
        return $GUID;
    }
    $string = generateNumber();
    return $string;
}

次に、for ループを使用してこれらのランダムな文字列を x 回生成し、MySQL テーブルに挿入できるようにする必要があります。

$how_manyループする回数を選択する場所です。

for ($i = 1; $i <= $how_many; $i++) {

        $random = $this->generateString();

        $query_params = array( 
            ':code' => $random,
        );
        $query = " 
            INSERT INTO table
            ( 
                code
            ) 
            VALUES 
            ( 
                :code
            )
        ";
        try { 
            $stmt = DB::get()->prepare($query); 
            $stmt->execute($query_params); 
        }  
        catch(PDOException $ex) {} 

    }

上記は私にエラーを与えます:

Fatal error: Cannot redeclare generateCharacter() (previously declared in....

関数を for ループに入れることができないことはわかっています。それ以外の場合はこのエラーが発生しますが、ループの外にある場合は、文字列が 1 回だけ生成され、毎回同じ文字列が挿入されます。

ループ内の各挿入が新しいランダム文字列になるようにするにはどうすればよいですか?

4

3 に答える 3

3

すでに書かれている関数を書かないでください。

PHP にはuniqid()という関数があります

マニュアルから

uniqid() マイクロ秒単位の現在の時刻に基づいて、プレフィックス付きの一意の識別子を取得します。

uniqid() によって返される値は 13 文字です。more_entropy がTRUEの場合、23 文字になります。

乱数を取得するには、rand()関数を使用できます。

コードでは、ループ内で同じステートメントを複数回準備します。これは非常に悪い習慣です。ループの前にステートメントを準備してから、ループ内のパラメーターのみを実行してバインドします。より効果的です。

于 2013-06-24T10:53:07.987 に答える
1

あなたはそれをより良く試すことができます:-

function generateString()
 {
  $number = base64_encode(openssl_random_pseudo_bytes(20, $strong));
  $newstr = preg_replace('/[^a-zA-Z0-9\']/', '', $number);
  return substr($newstr,0,10); return string of 10 random character 
 }
 ///same code after this
  for ($i = 1; $i <= $how_many; $i++) 
   {
    $random = $this->generateString();
    $query_params = array( 
        ':code' => $random,
    );
    $query = " 
        INSERT INTO table
        ( 
            code
        ) 
        VALUES 
        ( 
            :code
        )
    ";
    try { 
        $stmt = DB::get()->prepare($query); 
        $stmt->execute($query_params); 
    }  
    catch(PDOException $ex) {} 

}
于 2013-06-24T11:02:18.410 に答える
0

何が起こるかを簡単に説明しようとするので、技術的な観点から完全に正しくない可能性がある用語を使用します。

コードでは、2 つの内部関数generateCharacterとが外部関数の本体generateNumber定義されています。generateString

最初は、外側の関数 ( generateString) のみが残りのコードで「使用可能」です。

外側の関数が呼び出されると、2 つの内側の関数が「定義」され、グローバル スコープで使用できるようになります。つまり、内部関数は実際には非公開ではありません。クラス スコープではなく、グローバルにエクスポートされます。

外側の関数を 2 回以上呼び出すと、内側の関数が複数回 "定義" されます。まるでグローバルスコープgenerateStringで手動で複数回定義するかのようです。エラーのため、これは PHP では許可されていません。


考えられる修正:

  • 内部関数をグローバル スコープに移動します (とにかく最初の呼び出しでそこにエクスポートされます)。これは最悪の方法です。

  • makegenerateCharacterおよびgenerateNumber単純なプライベート メソッド。

  • uniqid他の回答で提案されているように、PHPを使用してください。


ここでは、何が起こるかを確認するための単純化されたシナリオを示します。

class Test {
  public function aaa() {
    function bbb() {
      echo("bbb");
    }
    echo "aaa";
    bbb();
  }
}

// bbb(); // would produce fatal error: undefined function bbb()
$test = new Test();
$test->aaa(); // outputs "aaabbb"
bbb(); // ok here, outputs "bbb"
于 2013-06-24T11:01:26.710 に答える