684425 Posted December 27, 2014 Share Posted December 27, 2014 (edited) I am trying to create a registration form where users put their name, email and password only. but i want to write an auto generated account number into database table for each user e.g; XY1234567 where XY should not change 1234567 auto generated random number and no duplicates (in numbers only). example... XY1234567 XY2345678 XY2233455 i found code $num_of_ids = 10000; //Number of "ids" to generate. $i = 0; //Loop counter. $n = 0; //"id" number piece. $l = "AAA"; //"id" letter piece. while ($i <= $num_of_ids) { $id = $l . sprintf("%04d", $n); //Create "id". Sprintf pads the number to make it 4 digits. echo $id . "<br>"; //Print out the id. if ($n == 9999) { //Once the number reaches 9999, increase the letter by one and reset number to 0. $n = 0; $l++; } $i++; $n++; //Letters can be incremented the same as numbers. Adding 1 to "AAA" prints out "AAB". } but its not working as i want. Any help please? Edited December 27, 2014 by 684425 Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/ Share on other sites More sharing options...
yozyk Posted December 27, 2014 Share Posted December 27, 2014 (edited) http://php.net/manual/en/function.uniqid.php Is it what you are looking for? Edited December 27, 2014 by yozyk Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500835 Share on other sites More sharing options...
684425 Posted December 27, 2014 Author Share Posted December 27, 2014 (edited) not this because it generates alphanumeric random output and i want XY(random, unique integer, fixed length) = XY9162942 or XY6433389 Sorry i forgot to mention fixed length in previous post. Edited December 27, 2014 by 684425 Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500838 Share on other sites More sharing options...
Jacques1 Posted December 27, 2014 Share Posted December 27, 2014 Don't use code you found somewhere on the Internet. Most of it is crap. Why do the numbers have to be random? Do they just have to be random-looking, or is it important that they are indeed unpredictable? One thing is for sure: Random and unique and only 7 digits long will be difficult. Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500839 Share on other sites More sharing options...
hansford Posted December 27, 2014 Share Posted December 27, 2014 Not sure of what you want exactly, but I used your code. <?php $num_of_ids = 10000; //Number of "ids" to generate. $i = 0; //Loop counter. $n = 0; //"id" number piece. $l = array("AAA","AAB","ABA","BBA","ABB","BBB","BAB","BAA"); //"id" letter piece. $count = 0; while ($i <= $num_of_ids) { $id = $l[$count] . sprintf("%04d", $n); //Create "id". Sprintf pads the number to make it 4 digits. echo $id . "<br>"; //Print out the id. if ($n == 9999) { //Once the number reaches 9999, increase the letter by one and reset number to 0. $n = 0; $count++; if (count($l) == $count) { break; } } $n++; //Letters can be incremented the same as numbers. Adding 1 to "AAA" prints out "AAB". } Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500840 Share on other sites More sharing options...
ginerjm Posted December 27, 2014 Share Posted December 27, 2014 (edited) You said it's not working. Just what is it doing? I ran it and got just what the code is setup to do. It produces a sequence of numbers for trios of letters as in: AAA0001 AAA0002 ... ... AAA9999 AAB0001 AAB0002 .... and so on. That's what you coded. Edited December 27, 2014 by ginerjm Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500841 Share on other sites More sharing options...
Jacques1 Posted December 27, 2014 Share Posted December 27, 2014 (edited) I think the problem is that the sample code has absolutely nothing to do with the requirements. So instead of wasting our time with it, I'd rather start from scratch. Edited December 27, 2014 by Jacques1 Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500842 Share on other sites More sharing options...
hansford Posted December 27, 2014 Share Posted December 27, 2014 Each user is going to have a unique ID in the database - if that is tagged onto any sequence of random chars - the registration id will be unique. Why do they even need a registration id - a temp registration number attached to a url that is emailed to them I can see, but that will expire and be deleted from the database. Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500843 Share on other sites More sharing options...
ginerjm Posted December 27, 2014 Share Posted December 27, 2014 Let's see what the OP has to say. Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500844 Share on other sites More sharing options...
684425 Posted December 27, 2014 Author Share Posted December 27, 2014 Why do the numbers have to be random? Do they just have to be random-looking, or is it important that they are indeed unpredictable? just random looking and unique, because a registered user will need that account number to login to his account. One thing is for sure: Random and unique and only 7 digits long will be difficult. if possible and if you guide me, i want to do it. please guide Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500847 Share on other sites More sharing options...
684425 Posted December 27, 2014 Author Share Posted December 27, 2014 (edited) You said it's not working as exactly i want. i have an account in skrill, they have given me an account number eg; XX12345678 which they generated automatically for me. and its unique for every registered user. i want to do the same thing for users of my site. Edited December 27, 2014 by 684425 Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500848 Share on other sites More sharing options...
hansford Posted December 27, 2014 Share Posted December 27, 2014 (edited) <?php // make db connection $id = ''; while ( true ) { $id = uniqid(true); $query = "SELECT COUNT(*) FROM $table WHERE reg_id=$id"; $stmt->execute($query); if (($stmt->fetchColumn()) == 0) { break; } } // we have a unique id compared to anything in the db Edited December 27, 2014 by hansford Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500849 Share on other sites More sharing options...
Jacques1 Posted December 27, 2014 Share Posted December 27, 2014 This doesn't work. If two PHP processes come up with the same new number at almost the same time, then they're both allowed to have it. You'll end up with a duplicate. The uniqueness check must be done at database level with a UNIQUE constraint. You first try to insert the number, and if that fails, you try again with another number: <?php // MySQL error code define('MYSQL_ER_DUP_ENTRY', 1062); define('ACCOUNT_ID_PREFIX', 'XY'); define('ACCOUNT_NUMBER_LENGTH', 7); define('MAX_RETRIES', 3); // this should be in a separate file $database = new PDO('mysql:host=localhost;dbname=YOUR_DB;charset=utf8mb4', 'YOUR_USER', 'YOUR_PW', [ PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); $registration_stmt = $database->prepare(' INSERT INTO users SET account_id = :account_id '); /* * Generate a random account number and let the database check if it's unique. If the number is not unqiue, try again. * Give up after a certain number of attempts. */ $registration_successful = false; $failed_attempts = 0; while (!$registration_successful && $failed_attempts < MAX_RETRIES) { try { /* * If l is the desired number of digits, the possible numbers range from 0 to 10**l - 1. * For example, if l = 7, then the number is in the interval 0..9999999 */ $account_number = mt_rand(0, pow(10, ACCOUNT_NUMBER_LENGTH) - 1); $account_id = ACCOUNT_ID_PREFIX . str_pad($account_number, ACCOUNT_NUMBER_LENGTH, '0', STR_PAD_LEFT); $registration_stmt->execute(['account_id' => $account_id]); $registration_successful = true; // this is only executed if the query succeeded } catch (PDOException $registration_error) { $error_code = $registration_error->errorInfo[1]; // If the error was due to a violation of the UNIQUE constraint, catch it and try again; otherwise rethrow it if ($error_code == MYSQL_ER_DUP_ENTRY) { $failed_attempts++; if ($failed_attempts == MAX_RETRIES) { throw new Exception('Gave up trying to generate unique account ID after ' . MAX_RETRIES . ' attempts. The pool might be exhausted.'); } } else { throw $registration_error; } } } Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500851 Share on other sites More sharing options...
hansford Posted December 28, 2014 Share Posted December 28, 2014 The uniqueness check must be done at database level with a UNIQUE constraint Absolutely. An id wouldn't be much good if it wasn't unique within the database. If two concurrent processes attempt to create the same id - one of them will succeed the race condition and the other will fail with an error. Quote Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500866 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.