684425 Posted December 27, 2014 Share Posted December 27, 2014 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? 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 http://php.net/manual/en/function.uniqid.php Is it what you are looking for? 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 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. 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. 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". } 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 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. 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 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. 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. 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. 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 On 12/27/2014 at 6:20 PM, Jacques1 said: 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. Quote 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 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 On 12/27/2014 at 6:32 PM, ginerjm said: 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. 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 <?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 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; } } } 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 Quote 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. Link to comment https://forums.phpfreaks.com/topic/293407-account-number-help/#findComment-1500866 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.