为每个客户生成一个随机数

I have this section of a form I need for my customer signup sheet I am creating.

My goal is check if the customer exists, and if they do, output the customerid into an input box. If the customer does not exist, a 6 digit number should be generated in the input box instead.

Here my code:

if(!empty($row['customerid'])) {
    echo '<input class="input-xlarge focused" disabled id="focusedInput" name="customerID" value="'.$row['customerid'].'">';
} else {
    $six_digit_random_number = mt_rand(100000, 999999);
    $sql = "SELECT * FROM customers WHERE customerid='$six_digit_random_number'";
    $loop = 0;
    while($row = $result->fetch_assoc()){
        if($loop == 10) {
            echo "CANNOT GENERATE RANDOM NUMBER";
            die();
        }
        $six_digit_random_number = mt_rand(100000, 999999);
        $loop++;
    }
    echo '<input class="input-xlarge focused" disabled id="focusedInput" name="customerID" value="'.$six_digit_random_number.'">';
}

My question is, will the while loop actually stop duplicates from being made, or is there something I am overlooking?

--UPDATE I switched out my original $six_digit_random_number with a number that already exists in the database, and the while loop did not change the number at all.

So I guess my updated question is, how can I check if the number has been used before?

Then you have to do something like this ( untested )

   $sql = "SELECT customerid FROM customers WHERE customerid=:random_number";
   $stmt = $DB->prepare($sql);
  do{
       //generate random number
       $six_digit_random_number = mt_rand(100000, 999999);
       //search for it
       $stmt->excute([':random_number' => $six_digit_random_number]);
       if( !$stmt->fetch() ){
           //exit loop if it matches.
           break;
       }
  }while(true);


  //$six_digit_random_number  save user with the unique number

Let me break the logic down for you.

When you create a new user, you need an infinite loop. On each iteration of that loop

  • Make a random number
  • Check against existing

Now when fetch returns false that means the number was never saved, so just use break to exit the loop. The last value of $six_digit_random_number is still set. So, after you exit the loop insert the new user with that number.

Next user cannot have the same number because, fetch will return a result, and the loop will continue and generate a new number. And so on, until such time as it creates one not in use.

The main drawback is if you have a lot of users you could make a bunch of queries against the DB, make sure to set that field to be an int and have a Unique index in the schema. That will improve the query performance, as will returning only one field ( that's all you need ) instead of *

Make sense.

-note- I like to use the do{ }while(true); syntax for this as it's less likely to be mistaken as a typo latter. It's just more readable then using while(true){ } other then that the only difference is with a do loop the loop happens before the evaluation so do{ }while(0) will run 1 time where while(0){} will not. In this case that doesn't matter though.