PHP делает / во время сбоя подготовленного оператора - PullRequest
0 голосов
/ 18 ноября 2010

У меня есть код, предназначенный для запуска проверки в моей базе данных, чтобы увидеть, является ли данное значение уникальным, и если это так, вставить его в базу данных.Если он не уникален, повторяйте процесс, пока он не найдет уникальное значение.

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 ]

3 голосов
/ 18 ноября 2010

Чтобы уточнить мой комментарий ... Ваш сценарий сгенерировал случайное число, которое будет ~ 80% времени выше максимального значения типа int. Ваш запрос для проверки, если user_id уже был взят, вернул бы false (mysql позволяет запрашивать за пределами диапазона диапазона столбца, он просто говорит, что нет записи с этим идентификатором), но тогда запрос на вставку не будет выполнен, так как число будет быть уменьшен до максимального размера INT. Чтобы это исправить, вы переключаетесь на BIGINT или ограничиваете свой случайный диапазон.

0 голосов
/ 18 ноября 2010

Было бы лучше использовать поле auto_increment, чтобы вы могли просто вставить каждую запись, если имя пользователя имя будет уникальным.Вы можете получить идентификатор последней вставленной записи, используя mysql_insert_id () , если вам это действительно нужно.

Если вы действительно хотите, чтобы числа казались случайными, вы можете использовать некоторую запись (например,xor, или определенный бит перемешивания), чтобы сгенерировать другое число, которое вы всегда можете вычислить обратно к реальному идентификатору пользователя, который хранится в базе данных.

0 голосов
/ 18 ноября 2010

Предел mt_rand(1000000000,2147483647); Тип данных int не может обрабатывать более этого.

0 голосов
/ 18 ноября 2010

Попробуйте изменить столбец идентификатора на BIGINT против INT, так как кажется, что вы пытаетесь сгенерировать случайное число выше емкости типов INT.Вот почему он сбрасывает его до 2147483647, который является максимальным числом INT.

...