0

データベースでチェックを実行して、指定された値が一意であるかどうかを確認し、一意である場合は、それをデータベースに挿入することを目的としたコードがあります。一意でない場合は、一意の値が見つかるまでプロセスを繰り返します。

do {
    // Generate a new user ID (15 numbers) and check to make sure it doesn't already exist.
    $new_user_id = mt_rand(1000000000, 9999999999);

    // Generate a fake Login Email address and check to make sure it doesn't already exist.
    $new_username = rand_str(13, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890');
    $new_username_email = 'BP' . $new_username . '@web.com';

    // Generate a new fake password
    $new_password = rand_str(15, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()');

    // Check to make sure the extremely random Username and user ID doesn't already exist in the database
    // On the off chance that it does, we need to regenerate and try again.

    $preparedStatement = $connection->prepare("SELECT user_id, username FROM `{$mysql_table}` WHERE user_id = :new_user_id OR username = :new_username");
    $preparedStatement->execute(array(':new_user_id' => $new_user_id, ':new_username' => $new_username_email));
    $result_2 = $preparedStatement->fetchAll();

    //TODO Not sure if this is actually working if there is a duplicate entry
} while (!empty($result_2));

// Once it is unique, insert the values into the database

$preparedStatement = $connection->prepare(
    "INSERT INTO `{$mysql_table}` (
        open_id, 
        user_id, 
        username, 
        password
    ) VALUES (
        :open_id_value, 
        :user_id_value, 
        :username_value, 
        :password_value
    )");

    if (!$preparedStatement->execute(array(
        ':open_id_value' => $_SESSION['user'], 
        ':user_id_value' => $new_user_id, 
        ':username_value' => $new_username_email, 
        ':password_value' => $new_password
    ))) {
        $arr = $preparedStatement->errorInfo();
                    die(print_r($arr));                             
    } else {
    // Send the new user to the account settings page, where they can set up their account information
        $_SESSION['new_user'] = 1;
        //echo 'You are a new user!';
        header("Location: /account-settings/");
        exit;                       
    }

私が得ている問題は、mt_randによって生成された値が重複していることを示していることです。

Array ( [0] => 23000 [1] => 1062 [2] => Duplicate entry '2147483647' for key 1 ) 1

まず、なぜこのコードから重複エラーが発生するのかわかりません-何が問題なのですか?第二に、私が複製を取得する可能性がある場合、それは再生成され、機能するまで再試行することになっていますが、それは明らかに発生していません。

手がかりはありますか?

4

4 に答える 4

3

私のコメントを詳しく説明します...あなたのスクリプトは、最大80%の確率でintの最大値を超える乱数を生成しました。user_idがすでに取得されているかどうかをテストするクエリはfalseを返します(mysqlでは列の範囲制限外でクエリを実行できます。そのIDのレコードはないと表示されます)が、その数が原因で挿入クエリは失敗します。最大INTサイズに縮小されます。これを修正するには、BIGINTに切り替えるか、ランダムな範囲を制限します。

于 2010-11-18T04:41:00.617 に答える
0

INTタイプの容量を超える乱数を生成しようとしているように見えるため、ID列をBIGINTvsINTに変更してみてください。これが、INTの最大数である2147483647にドロップダウンする理由です。

于 2010-11-18T04:38:10.007 に答える
0

制限データ型はmt_rand(1000000000,2147483647);それint以上を処理できません。

于 2010-11-18T04:39:35.450 に答える
0

全体として、auto_incrementフィールドを使用する方がよいので、ユーザーが一意である限り、各レコードを挿入するだけで済みます。本当に必要な場合は、mysql_insert_id()を使用して、最後に挿入されたレコードのIDを取得でき ます。

数字を本当にランダムに表示したい場合は、暗号化(xorや特定のビットシャッフルなど)を使用して別の数字を生成し、データベースに保存されている実際のユーザーIDにいつでも計算して戻すことができます。

于 2010-11-18T06:44:57.103 に答える