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
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.