Generating a truly unique order id in PHP?
-
21-09-2019 - |
Question
I'm considering using this: http://phpgoogle.blogspot.com/2007/08/four-ways-to-generate-unique-id-by-php.html
My idea is to use a mixture between 2 and 3. But my question is that, although the chances are small, is there still a chance that two orders with the same order # can be generated if I substring the result to be only 5 characters long? What about 3? 2? 1? Surely if it's 1, there is a 1/(26 + 10) chance that the id will be the same?
Solution
Assuming your users are authenticated and have a user id:
$unique_id = time() . mt_rand() . $userid;
If the same user requests this page a second time in the same second, there will still be a chance of 1 in mt_getrandmax()
, which on my machine returns 2147483647. You can probably live with that?
If your users are not authenticated, you can use a hash of their IP address instead if you'd like.
OTHER TIPS
Why do you need a unique ID ?
If you want to generate a unique ID in your DB, then leave it to your DB, using auto-increment.
Anyway, you could use a combination of microtime() and rand(). You be pretty unique.
Edit, relative to OP's comment :
You can't have a "always unique" if. Or if you find how, you'll win a turing award.
Even better mathematical approches leaves you with a taste of "yes but once in 15645736536475 times, I'll get screwed".
Only way is to have counter, that you increment everytime you need a new ID. That's how DBs do. Why do you need the Id before inserting ?
If you're relying on a random string then yes, it is theoretically possible that two IDs will be the same. That's why a long random string is used, to make that possibility so unlikely as to be acceptable. The probabilities can be calculated: for example if an ID is composed of the current time (to the nearest second) and a random 5-character alphanumeric string, and supposing that 3 IDs are generated in the same second, then the odds of two (or more) being the same is: 1 - (38^5! / (38^5-3)! / 38^5^3) = 3.79e-8. Most people would agree that such odds are not low enough for practical applications, which is why the page you linked to suggests 10 characters instead.
If you have a session ID, username, etc. then you can use that in the order ID, to help matters.
taken from PHP’s uniqid’s manpage:
$better_token = md5(uniqid(mt_rand(), true));
though it might be better to leave the md5
-part out (reduces the number of tokens to 2^128)
if your using a database, then yes, you should let your DBMS handle the generation of id’s
You can use microtime and sha256 hashing, or without hashing.
$generate_order_id = hash('sha256', microtime() );