2

I have this script:

$rrezervim_id = rand(1, 5);
$result = mysql_query("SELECT rrezervim_id FROM pax_list WHERE rrezervim_id='$rrezervim_id'");
if(mysql_num_rows($result) == 1)
{
$rrezervim_id = rand(1, 5);
} 
else(mysql_num_rows($result) > 1);
{
  echo "$rrezervim_id";
}

What i am trying to do is To generate a Unique Random number using PHP and MySql i have the value inside table( rrezervim_id)[Values:1,2,3,5] so the only Random number that have to be generated and is free is Number 4. But with this script something is not working since i am getting even random that are already inserted in the table [Values:1,2,3,5].

Any one can help me, is very important to make a check in mysql before generating the unique number if already exist in table.

7
  • 3
    Why not just use the built in AUTO INCREMENT? This will ensure all numbers are unique. Commented Dec 14, 2013 at 0:13
  • would it make sense to take a list of all possible numbers, then select all those that are not taken? That becomes the "list of valid IDs" from which you then select a random one. Commented Dec 14, 2013 at 0:13
  • Do you really need to generate numbers by yourself? Seems like job that AUTO_INCREMENT will do just fine. Commented Dec 14, 2013 at 0:14
  • no for my project i need a script just like i have explained the AUTO_INCREMENT will not work for what i am trying to do. Commented Dec 14, 2013 at 0:17
  • you have some syntax mess there - notice: else (...); { } <- it means that only the stuff in brackets runs under the 'else' part Commented Dec 14, 2013 at 0:18

3 Answers 3

2

First of all, the direct error in your code is

if(mysql_num_rows($result) == 1)
{
  $rrezervim_id = rand(1, 5);
} 

fails, if you hit a taken number twice. You need a loop, such as

while (mysql_num_rows($result) == 1)
{
  $rrezervim_id = rand(1, 5);
  $result = mysql_query("SELECT rrezervim_id FROM pax_list WHERE rrezervim_id='$rrezervim_id'");
}

That said, I suspect, that there is more wrong with your code:

  1. If you want to use this "free" random number to insert it into the database at a later point in time, you are wide open to a race condition: Both processes select the same (still free) number, but only on the first insert is it still unique.

  2. This approach can have extremely bad performance, if your field of possible random numbers is nearly full: If you have 80% fill rate, such as in your example, you will on average have 4 "bad" hits, before getting a "good" hit.

I recommend you consider using a database built-in, such as the battle-proven AUTO_INCREMENT as a primary means, then use a formula to create the hard-to-guess pseudo-random from it. A linear feedback shift register can be one approach, while cryptographically combining the auto-generated ID and a (not necessarily unique) pseudo-random stored in the table might be another. Both methods give you linear performance and race-free usage.

Sign up to request clarification or add additional context in comments.

Comments

0

you can create unique number in php

<?php
   echo uniqid();
?>

But you should use AUTO INCREMENT. If you want to know by which number inserted item is saved use something like this:

function insertUser(){
 Global $userName;
 $sqlInsert="INSERT INTO person (e_mail) 
    VALUES ('".$userName."')";
 if (!mysql_query($sqlInsert)){
    die('Error: ' . mysql_error());
 }
 $userId = mysql_insert_id();
 return $userId;
}

in $userId is last inserted value

Comments

0

Since you are not using AUTO_INCREMENT, a suggestion (which is slow) is to select all the numbers that are valid and pick 1 randomly.

If we have [1,2,3,5,7] and our allowed elements are 1..10, then we have 5 allowed elements(4,6,8,9,10). So we rand(1,5). If we get "1", our next number is 4, if we get "2", our next number is 6. To better explain the idea:

Rand(1,5)  Our array   Value(available)
           1
           2
           3
1          -           4
           5
2          -           6
           7
3                      8
4                      9
5                      10

Code example:

$max_num = 100;
$res = mysql_query("SELECT rrezervim_id FROM pax_list ORDER BY rrezervim_id ASC");
$nums = [];
while($row = mysql_fetch_assoc($res)){
    $nums[] = $res['rrezervim_id'];
}
$numbers_allowed = $max_num - count($nums);  // actual number of allowed elements
$new_num_idx = rand(1, $numbers_allowed);    // The selected element's index 
                                                (skipping all existing elements)
// in the following loop: $j starts as our lowest options.
// when $new_num_idx reaches 0 - it means that we have skipped
// over $new_num_idx elements. The next available element is
// our choice. $new_num_idx is a countdown
for($i=0,$j=1, $n=count($nums); $i<$n && $new_num_idx > 0; $i++){
    while ($nums[$i]>$i+$j){
        $j++; $new_num_idx--;
    }
}
return $i+$j;

3 Comments

look like what i need, but i am getting an error $nums = []; Parse error: syntax error, unexpected '[' in @galchen
change it to $nums = array(); then, or update your PHP version
take in mind - I didn't test it, didn't even go over it to see if the code might actually work. just wrote a few lines to show more or less what you might be looking for. If you want me to help you test it let me know

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.