i made a small code that generates different type of code, but i'll make it simpler,
i have a registration form submitted while submitting i collect some info about the user and i create for him a random, but i want this random to be unique for this user.
so i have 3 cases :
$code_random = rand(1000,9999);
if($code_random < 0){
$code_random = -$code_random;
}
$random = $fname.$code_random; //case 1
$random = $lname.$code_random; //case 2
$random = $fname.lname.$code_random; //case 3
But i want to create case 1 check if this random exist in the database, if it does use the second case if it does use the third case, before submitting the form and without displaying anything for the user.
Thanks for your help in advance.
Don't reinvent the wheel - SQL databases have two great ways of assigning unique IDs to every row.
1) Auto-incrementing primary key - goes up by one for every new row. Managed by the database, guaranteed to not use the same value for two rows by mistake. Nice and small and simple. http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
2) GUIDs (also known as UUIDs) - The algorithm used to generate GUIDs means that you'll never see the same one twice, ever. Over auto-incrementing integers, they have the advantage of being unpredictable, being generateable outside of the database and being meaningful outside of their database table context. http://www.php.net/manual/en/function.uniqid.php#94959 http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_uuid
If you really want to use a random integer, you can use the MySQL - rand() function for this
insert into users (id, ...) values (FLOOR(1000 + RAND() * (9999 – 1000)), ...)
There is a simple way of making infos unique: Create a unique index on the database column.
Then simply insert what you want and check if the database complains about violating the unique index. If this is the case, use one of your alternative queries and check again.
What if the last query still does not work?
Related
I want to randomly create a number of an user id, but it shouldn't be repeated/duplicated.
I wanted to ask if there is a good approach in general if my aim is to INSERT it into in a MySQL database? I don't want to create a new user. Its for another table.
I want to insert random data with random user id's to create test-comment entries users have made, but not I want to display different users. That's why I need it. It's not about autoincrementing with primary key in the main user table. I want to fill out a comment section
Example:
user_id: 54,34,30 randomy generated with PHP (mt_rand() function). Now I have about 1000 users I want to randomize, but there's still a chance it could be repeated at some point. So let's say now these are the values: 54,54,32
This means it will insert a same user twiche in further steps, where I INSERT this user id in the comment table.
So I just need another number randomly generated if it's already has been generated.
The best approach would be to create a GUID, rather than an integer. PHP has built-in methods to create these unique codes.
If you are inserting into a database, I would think that the most robust approach would be to create a primary key, and insert your entries one at a time. Since the DB call will error if you try to insert a duplicate ID, that's an appropriate place to check for an error and choose a different ID if you need to - although if you use a GUID, the chances of duplication are already negligible.
EDIT:
So if I understand what you are trying to do correctly, you want to create an array of random arrays of user ids, which are integers between 1-1000, where no two ids are repeated.
I am assuming that performances is not a big issue, since this sounds like test/dummy data. So the simplest way, in my opinion, would be to avoid having to test for an existing id on each id creation, and just shuffle your array.
So, you start with an array of 1000 ids, and then you loop through x number of times, shuffle the array, and slice off a random number of ids from the beginning of the array. Here is some code I have tested. It outputs what I think you want to create.
$ids = array();
$commentIds = array();
$numIds = 1000;
$numComments = 10;
for($i=0; $i<$numIds; $i++)
{
$ids[$i] = $i;
}
for($s=0; $s<$numComments; $s++)
{
shuffle($ids);
$num = mt_rand(1,10);
echo("rand:$num");
$commentIds[$s] = array_slice($ids,0,$num);
print_r($commentIds[$s]);
}
Is that what you mean?
If you have a specific number of users you want to add in, try just incrementing a digit and using that as the username. That way, they're all unique, and you don't have to force kill it after 30 seconds. This should be the easiest way of doing it, unless you need actually random (non-sequential) ids.
I'm using mysql database auto-increment as an order ID. When I display the order ID to the user, I want to somehow mask/obfuscate it.
Why?
So at first glance, it is obvious to admin users what the number
refers to (orders start with 10, customers start with 20 etc)
To hide, at first glance, that this is only my 4th order.
Based on this this answer, I want the masked/obfuscated order id to:
Be only numbers
Consistent length (if possible)
Not cause collisions
Be reversible so I can decode it and get the original ID
How would I acheive this in PHP? It doesn't have to be very complex, just so at first glance it's not obvious.
I think you can use XOR operator to hide "at first glance" for example (MySQL example):
(id*121) ^ 2342323
Where 2342323 and 121 are "magic" numbers - templates for the order number.
To reverse:
(OrderNum ^ 2342323)/121
Additional advantage in this case - you can validate OrderNumber (to avoid spam or something like this in online form) if (OrderNum ^ 2342323) is divided by 121 with no remainder.
SQLFiddle demo
A little bit late, but Optimus (https://github.com/jenssegers/optimus) does exactly what is here asked for.
$encoded = $optimus->encode(20); // 1535832388
$original = $optimus->decode(1535832388); // 20
Only the initial setup is a bit weird (generate primenumbers)
Probably the simplest way is to just generate a long random string and use it instead of the auto-increment ID. Or maybe use it alongside the auto-increment ID. If the string is long enough and random enough, it will be unique for every record (think of GUIDs). Then you can display these to the user and not worry about anything.
Can it help?
echo hexdec(uniqid());
Off course you should store this value at db, at the same row with order id.
Just converting a ID into something like HEX might not give you the result what you like. Moreover its still easy 'guessable'
I would a a extra ID column (i.e. order_id). Set a unqi. index. Then on_creation use one of the following mysql functions:
SHA1(contcat('ORDER', id))
MD5(contcat('ORDER', id))
SHA1(contcat('ORDER', id, customer_id))
MD5(contcat('ORDER', id, customer_id))
UUID()
// try this in your mysql console
SELECT UUID(), SHA(CONCAT('ORDER',10)), SHA1(1);
You could (as in the example), add a simple text prefix like 'order'. Or even combine them. However i think UUID() would be easiest.
Implementation depends a bit on what you prefer you could use a stored procedure) or incorporate it in your model.
Suppose Table1 contains column orderid (not a key, although it's NOT NULL and unique). It contains 5-digit numbers.
What's the best way to generate a php var $unique_var that is not in that column.
What could be important, from 10% to 30% of 5-digit numbers are in the table (so generating a number and checking while (mysql_num_rows() ==0) {} is not a best way to find one, are there any better solution for performance?).
Thank you.
If there is just 10-30% of numbers already taken - then it means that only 10-30% of queries will be performed at least twice. Which is not a big performance issue at all.
Otherwise - just create all-5-digit-numbers-list table (just 100k rows) and remove all that exist. When you need another random number - just pick one and delete.
I would suggest finding the biggest number (with a MAX() clause) and start from there.
Here are a couple of suggestions. Each has its drawbacks.
Pre-populate your table and add a column to indicate that a number is unused. Select an unused number using LIMIT = 1 and mark it used. This uses a lot of space.
Keep a separate table containing previously used numbers. If that table is empty, generate numbers sequentially from the last used number (or from 00001 if Table1 is empty). This requires some extra bookkeeping.
i've got hundreds of people joining my website and create an membership id for them. i just created a new column in the database called user_no.
whats the mysql query for incrementing the membership no.
is it possible to start with AE then numbers ie: AE0001, AE0002, .... and it starts with 4 number not AE1, AE2..
mysql query:
UPDATE user SET user_no=..??
and on PHP side, how do i increment it? if there is a new member join in.
$db->query("INSERT INTO user (user_no) VALUES(AE'$user_no')");
Why not use an autoincrement field and append AE to it? Autoincrement will be carried out by MySQL so you don't have to worry about it in PHP : http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
And to display your user key in the format of AE0001 you can do
$id = 'AE' . str_pad($autoincrementid, 5, "0", STR_PAD_LEFT);
http://php.net/manual/en/function.str-pad.php
I agree with everyone else who is saying that you should simply use the MySQL Auto-increment feature. That's what it's there for.
It is possible to write your own, possibly using MySQL's MAX() function to find the highest value of a field currently in the table. However unless you're using some very robust transactional code, there is always the danger that this method will result in duplicate records being created when two users create accounts at exactly the same time.
The amount of code required to avoid this is not small, and if you're inexperienced enough not to see the benefits of using Auto-increment then you're unlikely to get it right.
The whole point of Auto-increment is to save you from having to implement all that code every time.
In addition, it is highly recommended for performance reasons to use an integer value for your primary key. Sure, you can display it as "AE" . $id, but you should store it as an integer on the database.
I have two functions, makeKey() and keyExists().
makeKey() simply generates a 5 digit random alphanumeric key, keyExists() accepts this key as its only argument, and looks up in a table, returning true/false depending on whether it exists.
I need to do something very simple but I cannot figure out the quickest way of doing it.
I just need to make a key, and if it exists in the table, make a key again, and so on until a unique one is returned. I think a while loop will suffice?
Thanks and please forgive the rather basic question, I think I cooked my brain in the sun yesterday.
I’d use a do-while loop:
do {
$newKey = makeKey();
} while (keyExists($newKey));
This will generate a new key on every iteration until the key does not exist yet.
Any solution that relies on creating, then checking is going to have awful performance as the key space fills up. You'd be better off generating a unique key using an autogenerated column (identity or guid). If it needs to be alphanumeric, use a mapping function to transform it into the alphabet of your choice by selecting groups of bits and using them as an index into your alphabet.
Pseudo-code
alphabet = "ABCDE...789";
key = insert new row, get autogenerated key
alphaKey = "";
while (get n bits from key)
alphaKey += alphabet[bits]
done
echo alphaKey
my php is a little rusty, so consider this pseudo-code:
$key_exists = true;
while($key_exists) {
$key = generateKey();
$key_exists = checkKey($myKeysHash, $key);
}
// $key is now unique and ready to use
Why not use a built in php function like uniqid()?
You mention a table, so I'm wondering if you are storing these keys in a database? If so, your approach is going to have a race condition - you might check a key is OK to use right before another process uses that key.
A better approach is generate a possible key and then attempt to persist it - perhaps by performing an INSERT onto a table of keys and retrying with different keys until it succeeds.
I'll also assume you're using some sort of database.
Could you not use a unique auto-increment ID column in the database? It would remove the requirement to check if the key exists since the database engine will never assign the same ID twice.
However, you'd have to change the logic in your application rather than just coding up new functions.
Does it need to be random? Just increment a variable and store the next one to be used in another field.
while (keyExists($newKey = makeKey()));
Probably the quickest way of doing the check, if a key exists it will generate a new one. If you start having a lot of collisions/needing to check the database many times before getting a new unique key, you probably will want to rethink your makeKey() algorithm. Calls to the DB are expensive, the fewer calls you can make the faster and more efficient your script will be.
If you're not fixed on a 5-digit number, you could think about using a hash of your id + a name column.