PHP do/while 准备语句失败

发布于 2024-10-03 06:02:17 字数 2527 浏览 9 评论 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

首先,我不知道为什么我会从这段代码中收到重复的错误 - 它有什么问题?其次,如果我确实得到了一个副本,它应该重新生成并重试直到它起作用 - 但这显然没有发生。

有什么线索吗?

I have a code that is meant to run a check on my database to see if a given value is unique, and if so, insert it into the db. If it isn't unique, reiterate the process until it finds a unique value.

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;                       
    }

The problem that I'm getting is that the value generated by mt_rand says that it is a duplicate.

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

Firstly, I don't know why I'd be getting a duplicate error from this code - what is wrong about it? Secondly, on the chance I DO get a duplicate, it is supposed to regenerate and try again until it works - but that is obviously not happening.

Any clues?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

栖竹 2024-10-10 06:02:17

为了详细说明我的评论...您的脚本生成了一个随机数,该随机数在大约 80% 的情况下会高于 int 的最大值。您测试 user_id 是否已被采用的查询将返回 false (mysql 允许您查询列的范围限制之外,它只是说没有该 id 的记录),但是插入查询将失败,因为数字将减少到最大 INT 大小。要解决此问题,您可以切换到 BIGINT 或限制随机范围。

To elaborate on my comment...Your script generated a random number that will ~80% of the time be above the max of an int. Your query to test if the user_id had already been taken would return false (mysql allows you to query outside the range limit of a column, it just says there's no record with that id), but then the insert query would fail since the number would be reduced to the maximum INT size. To fix this you switch to BIGINT or limit your random range.

南烟 2024-10-10 06:02:17

尝试将您的 ID 列更改为 BIGINT 与 INT,因为您似乎正在尝试生成高于 INT 类型容量的随机数。这就是为什么它将其降至 2147483647(INT 最大数)的原因。

Try changing your ID column to BIGINT vs INT as it appears your are trying to generate random number above INT types capacity. This is why it's dropping it down to 2147483647 which is INT max number.

你是年少的欢喜 2024-10-10 06:02:17

限制 mt_rand(1000000000,2147483647); int 数据类型不能处理更多的数据。

Limit mt_rand(1000000000,2147483647); An int data type cannot handle more than that.

浮世清欢 2024-10-10 06:02:17

最好使用 auto_increment 字段,这样只要用户名是唯一的,您就可以插入每条记录。您可以使用以下命令检索最后插入的记录的 id
mysql_insert_id() 如果你确实需要它。

如果您确实希望数字随机出现,您可以使用一些加密(如异或或特定位洗牌)来生成另一个数字,您可以随时将其计算回存储在数据库中的真实用户 ID。

It would altogether be better to use an auto_increment field, so you could just insert each record as long as the user name would be unique. You can retreive the id of the last inserted record by using
mysql_insert_id() if you really need it.

If you really want the numbers to appear random, you can use some encription (like xor, or a specific bit shuffle) to generate another number which you can always calculate back to the real userid which is stored in the database.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文