1

I'm trying to generate a set of unique Alpha Numeric code in php. I tried using anonymous function and closures.
Here when I generate more than 1000 codes, there are changes of codes getting duplicate. So I tried to generate a new code if any duplicate found.
Below is my code which isn't working as expected, I'm getting "still DUPLICATE Exist" a few times and its not regenerating code even a single time.

$start = 0;
$count = 10;
$codes = [];
$another = $this;
for ($i=$start; $i < $count; $i++) {
    $getUniqueCode = function (&$codes) use ($another, &$getUniqueCode) {
        $newCode = $another->genRandomCode();
        if (in_array($newCode, $codes)) {
            echo "Regenerate on DUPLICATE FOUND - $newCode <br/>";
            return $getUniqueCode($codes);
        } else {
            return $newCode;
        }
    };
    $newCode = $getUniqueCode($codes);
    if (\in_array($newCode, $codes)) {
        echo "still DUPLICATE Exist - $newCode <br/>";
    }

    array_push($codes, $newCode);
}


private function genRandomCode()
{
    $str = "ABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789";
    $randInt = rand(1000000, 9999999);
    $randString = "";
    for ($i=0; $i < 6; $i++) {
        $randRem = $randInt % 36;
        $randInt = $randInt / 36;
        $randString .= $str[$randRem];
    }
    return $randString;
}
Ankit Balyan
  • 1,319
  • 19
  • 31

1 Answers1

1

Your original code recurses, but i don't think you need to do that.

$start = 0;
$count = 10;
$codes = [];
$another = $this;
for ($i=$start; $i < $count; $i++) {
    //do not pass $codes as a reference here
    $getUniqueCode = function ($codes) use ($another) 
    {
        $newCode = $another->genRandomCode();
        while(in_array($newCode, $codes))
        {
            echo "Regenerate on DUPLICATE FOUND - $newCode <br/>";
        }

        return $newCode;
    };

    $newCode = $getUniqueCode($codes);
    if (\in_array($newCode, $codes)) {
        echo "still DUPLICATE Exist - $newCode <br/>";
    }

    array_push($codes, $newCode);
}

Arguably however, a better way to handle a coupon system like this is to generate the possible coupon codes beforehand, store them in a database, and select one at random for activation. this guarantees a unique code, and lets you keep track of which codes you have used so far.

Timothy Groote
  • 8,614
  • 26
  • 52
  • This is just for generating codes before hands, I've mechanism for keeping a track of used, unused, times a code can be used etc etc. – Ankit Balyan Aug 04 '17 at 08:18
  • then why not generate them sequentially, and pick a random one that you have not used when you need it? (seems easier. just my $0.02) – Timothy Groote Aug 04 '17 at 08:19
  • I don't why `in_array($newCode, $codes)` give false always in the inner while loop. but "still DUPLICATE Exist" got printed outside. – Ankit Balyan Aug 04 '17 at 08:30
  • not even a single time this line "echo "Regenerate on DUPLICATE FOUND - $newCode
    ";" executes.
    – Ankit Balyan Aug 04 '17 at 08:31
  • @AnkitBalyan could the problem be caused by passing `&$codes` (as a reference) into the anonymous function? – Timothy Groote Aug 04 '17 at 08:40
  • 1
    I honestly don't know, and i can't run this code myself to check it right now, but try passing it like `$getUniqueCode = function ($codes) use ($another) ` (withouth the ampersand `&` ) – Timothy Groote Aug 04 '17 at 08:40
  • cool, I tried without `&` in my original code but it didn't work. It works. thanks. :) – Ankit Balyan Aug 04 '17 at 08:49
  • regarding generating them sequentially, as I wouldn't know how a 3rd party who is distributing code will going to reveal, As I'm just gonna give them all codes at once. – Ankit Balyan Aug 04 '17 at 08:50
  • @AnkitBalyan well, glad to be of help :) happy coding. – Timothy Groote Aug 04 '17 at 08:53