I read several topics similar to what I'm asking, but none of them seemed to be very helpful to me.

I have a form where users can generate codes that are stored in a column with a Unique constraint. The codes are strings with length of 7 characters. The users can enter a number and the program generates that many codes, and this can be repeated until the maximum number of codes is reached.

My problem is with duplicate values. But not with values that are already present in the database in the moment of entering new entries(I check for those successfully), but some of the entries in the new group of (say 10000) codes are (probably) identical. So my code generates two(or more) identical codes in the same transaction and the Unique constraint in the DB complains about it.

I thought of checking the database after each entry, but it is extremely time consuming, considering we're talking about 10000 or sometimes more entries.

So now I think the only option is to modify the code that generates them in the first place, cause it seems to be inefficient and generate doubles.

A big part of the problem is the required length of the codes, otherwise I would go with pure 'uniqid()' or something similar, but since I have to restrict it to 7 characters I guess that makes it a lot worse. Also, I have to exclude some characters from the code[labeled 'problem_characters'] in the code.

Here's the code, I couldn't modify it properly to generate unique values only.

$problem_characters = array("0", "o", "O", "I", "1", 1);

$code = md5(uniqid(rand(), true));

$extId = strtoupper(str_replace($problem_characters,rand(2,9),substr($code, 0, 7)));

//insert $extId in the database

In your case, this is what I would do, I'm not sure how many duplicates you are getting in a set of say, 10,000 codes, but I would start with a set number, say 50 or 100.
so function_being_called($number_to_return) where $number_to_return is your 10000.
Add 50 or 100 to that number. call your $code code.

// initialize an array
$temp_array = array();
// push each value of $extId into that array.
array_push($temp_array,$extId);
// call unique on that array.  
$ids = array_unique($return_array); 
// then using foreach, you can insert each id, you can limit it with a counter 
// I'm sure there may be cleaner code but this is quick
$return_count = $number_to_return;  // this would be the original # like 10,000
$count = 0;
foreach($ids as $id) {  
    // compare $cnt to your $return_count which holds the number of times you want to insert.
    if ($count <= $return_count) {
        // insert $id into database;
    }
    $cnt++;
}

// you should at this point have inserted 10,000 or so, unique ids.

So, to sum it up, initialize a temp array, take the number passed in (z) and add (x) to it so it produces 10,050 or 10,100 records (because some of these records are duplicates)
put each of those extIds into an array, call unique_array on that array.
then only use (z) records that you are holding in that array and insert them into your db, use a counter to only insert (z) results

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.