1

私は PHP を学んでいて、while と continue 式を正しく使用しようとしています。

6 桁の PIN を作成するスクリプトがあり、それが一意であることを確認したいのですが、それ以外の場合は別の PIN を生成したいと考えています。

while(1) {
    $pin = rand(111111,999999);
    $sel = mysql_query("SELECT * FROM formusers WHERE pin = '$pin'");
    if(mysql_num_rows($sel) != 0) { continue; }

    mysql_query("INSERT INTO formusers(email,password,pin) VALUES('".$_POST['srEmail']."','".$_POST['srPass']."','".$pin."')");
    if(mysql_affected_rows()!=-1)  {
        echo "Pin:" . $pin;
        exit;
    } else {
        echo "Existing email, try again<br />";
    }
    break;
}

ループの構文は正しいですか? 動作しているように見えますが、rand() 関数が同じ PIN を 2 回作成するインスタンスでデバッグする方法はありません。

また、固有の PIN を使い果たした場合、ここではどうなりますか? おそらくそれは無期限にループするでしょうか?これを防ぐ方法はありますか?

4

3 に答える 3

2

ええ、コードは機能しますが、前述のように無限ループが懸念されます。次のように解決できる可能性があります。

var $i = 0;

while($i < 10) {
    $i++;

    $pin = rand(111111,999999);
    $sel = mysql_query("SELECT * FROM formusers WHERE pin = '$pin'");
    if(mysql_num_rows($sel) != 0) { continue; }

    mysql_query("INSERT INTO formusers(email,password,pin) VALUES('".$_POST['srEmail']."','".$_POST['srPass']."','".$pin."')");
    if(mysql_affected_rows()!=-1)  {
        echo "Pin:" . $pin;
        exit;
    } else {
        echo "Existing email, try again<br />";
    }
    break;
}

これにより、反復が 10 回を超えないようにすることができます。ただし、より大きな問題は、そのサンプリング サイズでさえ、将来的には機能しなくなる可能性があることです。これはちょっとした難問を提示します。考えられるアプローチの 1 つは、ループを開始する前に一意の数をカウントしてその数を決定し、それを何度も繰り返すことですが、そのアプローチは n 2のようなものです (たぶん、私は big-O があまり得意ではありません。ダメでしょう)。

于 2013-07-22T19:02:05.710 に答える
2

これには、php 配列キーの固有の性質を利用できます。

function getPins($qty){
    $pins = array();
    while (count($pins) < $qty){
        $pins[rand(111111,999999)] = ""; 
    }
    return array_keys($pins);
}

これにより、特定の実行で $qty 個の一意のピンを確実に取得できます。関数の各実行に一意のプレフィックスを追加して、複数回の実行で 2 つの間の衝突が発生しないようにすることをお勧めします。

于 2013-07-22T19:07:33.767 に答える
0

ランダムにシードできるため、実行するたびに同じ値が得られます。

srand (55 );  //Or some other value.

while ループの構文は問題ないように見えます。

于 2013-07-22T18:54:42.580 に答える