1

I know that the goto statement is frowned upon but I wanted to know if the following situation would make it the most acceptable.

I want to create a unique random number for a column value but to do that I need to create a random number and check to see if it exists in a table.

a:
$rnumber = rand(1, 10);
$queryresult = $mysqli->query("SELECT uniquerandomcolumn FROM tbldata WHERE uniquerandomcolumn =" . $rnumber);

if ($queryresult->num_rows > 0) //if random number exists a row would be returned
{goto a;}  //try again
else {//insert into table}
Ralph
  • 889
  • 14
  • 25

5 Answers5

6

Use this instead, so the number will be unique

$id = uniqid(rand(), true);
The Alpha
  • 143,660
  • 29
  • 287
  • 307
3

You don't need goto for that.

do
{
    $rnumber = rand(1, 10);
    $queryresult = $mysqli->query("SELECT uniquerandomcolumn FROM tbldata WHERE uniquerandomcolumn =" . $rnumber);
}
while($queryresult->num_rows > 0);
//insert into table}

EDIT: This answer is just to prove that goto isn't necessary in the original code. In this particular example, I would advise against using this code and use WereWolf - The Alpha's answer in your code.

CHRIS
  • 957
  • 3
  • 10
  • 27
  • Thanks everyone for the clarification, now I know to use a loop. The do, while example here seems to be what I'm looking for. Keep looping until the random number isn't found in the db table. – Ralph May 25 '13 at 17:46
  • 2
    @Ralph this is working but a bit dangerous (the loop may run a lot for nothing) - you may want to try *randomly* all 10 numbers, *never* twice the same number, and *only* 10, not more (see my solution below). – Déjà vu May 25 '13 at 17:51
  • I know what you would tell me.But I think its not correct because the code -Ralph- posted needs to check else but this is not checking that. (check my answer for that please). – Sina R. May 25 '13 at 17:53
  • There is no need for the else. All code under the while will happen once a random number has been selected which is not in use. It does the same thing as the else. – CHRIS May 25 '13 at 17:55
  • +1 to -ring0- yes I strongly recommend you to prevent that and also I suggest to first store the list of all records in array and check it with rands. – Sina R. May 25 '13 at 18:03
2

Instead, you should use a while loop, that counts retry attempts:

$attempt = 0; $success = false;
while ($attempt++ < 3) {
    // ... make sure $success gets marked true!
    // in case of success, make sure you break here!
}
if (!$success) {
    // Failure
}

This makes sure your script never freezes (infinite loop).

cutsoy
  • 10,127
  • 4
  • 40
  • 57
  • `do` loops only make sense when performing a condition based on something within the block, I think. In this case it'd be quite unnecessary. – cutsoy May 25 '13 at 17:36
  • That describes this situation pretty exactly.... *do* a query, if it doesn't produce results, do it again. – Sam Dufel May 25 '13 at 17:38
0

The goto statement was mainly - if any - used for error processing: in a long list of statement, each of them being able to trigger an error, a jump (goto) was made near the bottom of the function to skip all the remaining statements, and run a common error processor at the end of the function.

But nowadays, even PHP has exception handling, thus the use of goto is even less justified.

Fix the problem as mentioned

In your case, you can implement a simple algorithm to perform the equivalent function

do {
  $rnumber = rand(1, 10);
  $queryresult = $mysqli->query("SELECT uniquerandomcolumn FROM tbldata WHERE uniquerandomcolumn =" . $rnumber);

} while ($queryresult->num_rows > 0);

having the risk of being in an infinite (or very long) loop...

Room for improvement

Since the number of tries is limited (1 .. 10), it would be better to

  • try all numbers from 1 to 10 (maximum) once without repetition
  • randomly (eg 7 2 3 9 ...)

ie, perform a maximum of 10 tries, and exit if the row does not exist or if all 10 tries have been done. To try randomly from 1 to 10, use the shuffle function to shuffle randomly an array of 1 to 10 elements.

$tries = array();
for ($i=1 ; $i<=10 ; $i++) $tries[] = $i; // create an array (1,2,3,4,5...)

shuffle ($tries); // shuffle the array, eg now $tries is (8,2,9,1,7...)

$index = 0; // start with first element of $tries
do {
  $rnumber = $tries[$index++];
  $queryresult = $mysqli->query("SELECT uniquerandomcolumn FROM tbldata WHERE uniquerandomcolumn =" . $rnumber);

} while ($queryresult->num_rows > 0 && $tries < 10);

This way you try randomly all 10 possible values, not more.

After the while add

if ($queryresult->num_rows < 1) {
  // found a non existing number: $tries[$index-1]
}
else {
  // all 10 numbers exist in the DB...
}

to deal with the two conditions.

Déjà vu
  • 28,223
  • 6
  • 72
  • 100
-1

goto isn't a good coding practice, it will make your code unaccountable and unmanageable. Don't ever use goto. Or else a velociraptor will hit you while you compiling your code.

enter image description here

But it's okay if you are making a console application, it's okay.