I want to generate a very uniue number on script runtime and it should never duplicate. I used floor(time()/86400) but if generates th esame number if the script runs on the same daye. also that unique number should not be the exact timestamp. so any idea how to generate a very unique and again unique at each run?

    What restrictions do you have on length/size, and does it have to consist only of digits (0-9)? If you have no special restrictions, the simplest thing is probably to use [man]uniqid/man. As you start adding restrictions, you start limiting the range of possible values. You then get to the point where you have to do something like recording each number used, and whenever you generate a new one you have to check to see if it's been used already, and if so start the process again. If you generate a lot of such values, you may start getting more such collisions and potentially have go through several iterations until an unused value is found.

      yes it must be a 9-digits thing. First I thought I could use substr to fetch 9 random digits from uniqid as it is unique itself but noticed it contains characters too. Also storing last numers and compare next ones to them to make sure these are unique is not good in my case. any better way to generate a very unique 9 digits things without storing last ones and then compare them?

        One way would be:

        echo mt_rand(100000000, 999999999);

        Be careful if you want to extend this to more than 9 digits as you may exceed the maximum integer value for the implementation. Also, note that you can expect duplicates after about 30000 numbers have been randomly generated (but of course a duplicate can occur on the second number that is generated, but that is very unlikely).

        If the numbers generated absolutely must never have duplicates, then you must record the numbers generated. If you cannot record the numbers generated, then your requirements are impossible to fulfill.

          The problem there is that 9 digits is not enough granularity for a time-based solution, as that would only give you about 10 seconds' granularity (in terms of a UNIX timestamp integer), so any two requests within 10 seconds of each other could have the same result. If you go with a random number generation - e.g.: rand(100000000, 999999999) - there's a small but real chance that any two instances will generate the same number, and as more numbers are generated that probability increases, of course. (A random number generator does not "remember" what its previous results were and then exclude them, just like a coin does not "remember" whether it came up heads or tails on the previous coin flip, and so the odds are 50/50 for every flip.)

          So, unless you're sure no two requests would ever happen within 10 seconds of each other, the only option I see for a 9-digit unique number is some sort of tracking/recording system. Maybe a database solution where you have a table with one row with an integer column starting at 100000000. Then when you need a number, you update that value by adding one to it, and retrieve the new value. The down-side is that the numbers will be sequential, should that be an issue.

            I have a func fetch_database which search db and return the results as array and you can search that array. but in case if the second generated number is still duplicate, I don't know how to loop the following query. may you re-write it for me?

                        $item_number = mt_rand(100000000, 999999999);
                        $fetch_info = "SELECT id FROM numbers WHERE order_id = '$item_number'";
                        $results = fetch_database($fetch_info);
                        if (!empty($results)) {
                            // a row found with that number, re-generate it.
                            $item_number = mt_rand(100000000, 999999999);
                        }

              How about this? Can I be sure that is very unique?
              echo mt_rand(0000,9999).substr(time(), -5);

                Well, something is either unique or it is not. 😉

                As far as probabilities go, mt_rand(0000,9999).substr(time(), -5); would functionally be no different than mt_rand(0,999999999). There may be some very minor statistical differences that I'm not enough of a mathematician to recognize, but you're still just dealing with a 9-digit random number.

                  so how to loop the query I gave you in last two post to get a uninue number? how to loop it?

                    ehm.. Andre.. It is not clear to me what you are going to be using this for, so probably this is completely off but... Do you need them to be Unique & Random? Or can it be a sequential incrementing number? In the latter case, you could just use a counter, which you left-pad to reach 9 digits.

                      It depends on your database interface. I have no idea what fetch_database() does, so I shall give my example using the PDO extension:

                      // Check that the number is not already in the database.
                      $stmt = $db->prepare("SELECT COUNT(*) AS id_count FROM numbers WHERE order_id=:id");
                      $stmt->bindParam(':id', $item_number, PDO::PARAM_INT);
                      $id_count = 0;
                      do {
                          $item_number = mt_rand(100000000, 999999999);
                          $stmt->execute();
                          $row = $stmt->fetch();
                          $id_count = $row['id_count'];
                      } while ($id_count > 0);
                      
                      // Insert number.
                      $stmt = $db->prepare("INSERT INTO numbers (order_id) VALUES (:id)");
                      $stmt->bindParam(':id', $item_number, PDO::PARAM_INT);
                      $stmt->execute();

                      The above is vulnerable to a race condition. A better way would be to make the order_id column UNIQUE, and then attempt to insert:

                      $stmt = $db->prepare("INSERT INTO numbers (order_id) VALUES (:id)");
                      $stmt->bindParam(':id', $item_number, PDO::PARAM_INT);
                      do {
                          $item_number = mt_rand(100000000, 999999999);
                      } while (!$stmt->execute());

                        Please the second example with no class use. a non-OO example.

                          Please the second example with no class use. a non-OO example.

                          Do you understand that example?

                          Since I have no idea what database interface you are using, giving you another example would be pointless. The most important thing is to understand the idea behind the example, and then implement your own code.

                            Write a Reply...