Jump to content
Sign in to follow this  
684425

Account number help.

Recommended Posts

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 by 684425

Share this post


Link to post
Share on other sites

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 by 684425

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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".
}

Share this post


Link to post
Share on other sites

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 by ginerjm

Share this post


Link to post
Share on other sites

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 by Jacques1

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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  :) 

Share this post


Link to post
Share on other sites

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 by 684425

Share this post


Link to post
Share on other sites


<?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 by hansford

Share this post


Link to post
Share on other sites

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;
        }
    }
}

Share this post


Link to post
Share on other sites

 

 

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.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.