To make the codes unique you'll have to check if the generated code has already been generated.
You can accomplish this a couple of ways depending on your implementation.
If you're generating a bunch in a single script then do something like this:
<?php
//testing code remove for production
$num_codes = 10000;
$num_tries = 20;
echo 'generating codes';
flush();
$start_time = getmicrotime();
$codes = gen_codes($num_codes,$num_tries);
$end_time = getmicrotime();
$run_time = $end_time - $start_time;
echo 'Generated ' . $num_codes . ' in ' . $run_time . ' seconds<br>';
foreach(array_keys($codes) as $code) {
echo $code . ': ' . $codes[$code] . "<br>\n";
} //end foreach
//end testing code
//this function generates a series of codes with no repeats.
//it will exit and return the list when num_codes codes have
//been generated or max_tries duplicates are generated for a
//single code
/*array*/ function gen_codes($num_codes=0,$max_tries = 100) {
$codes = array();
$i = 0;
while(count($codes) < $num_codes && $i < $max_tries) {
//generate a random code
$code = gen_code(8);
//add it to codes if it's not already there
//if it is already there then increment the
//repeat counter
if(!in_array($code,$codes)) {
$codes[] = $code /*testing code*/ . ' - ' . $i /*end testing code*/;
$i = 0;
} else {
$i++;
} //end if
//testing code remove for production
if(count($codes)%100 == 0) {
echo '.';
flush();
}
//end testing code
} //end while
//testing code remove for production
echo '<br>';
//end testing code
return $codes;
} //end gen_codes
//this function will generate a single alpha
//numeric code that is len characters long
/*string*/ function gen_code($len = 6) {
$code = '';
for($i=0;$i<$len;$i++) {
switch (mt_rand(0,2)) {
case 0:
$code .= chr(mt_rand(65,90));
break;
case 1:
$code .= chr(mt_rand(97,122));
break;
case 2:
$code .= mt_rand(0,9);
} //end switch
} //end for
return $code;
} //end gen_code
//testing code remove for production
function getmicrotime()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
//end testing code
?>
On my server this code generated 10000 codes in 29.313146829605 seconds
Now if you're only generating one code per run then you'll have to save the already generated list to a file and check if your new code is in that file with something like this.
<?php
//testing code remove for production
$file_name = '../../data_files/unique_codes.txt';
echo 'generating code<br>';
flush();
$code = gen_unique_code($file_name);
if($code != 0) {echo $code . '<br>';}
else {echo 'Could not generate unique code<br>';}
//end testing code
//this function generates a code that does not already exist in the file
//file pointed to by file_name. If max_tries repeated codes occur then
//the function returns zero.
/*string*/ function gen_unique_code($file_name = 'unique_codes.txt',$max_tries = 10000) {
//read the already generated codes into an array;
if(file_exists($file_name)) {$codes = file($file_name);}
else {
$handle = fopen($file_name,'w');
fclose($handle);
chmod($file_name,0777);
$codes = array();
} //end if
//remove the line returns from the codes file
for($i=0;$i<count($codes);$i++) {
$codes[$i] = rtrim($codes[$i]);
} //end for
$i = 0;
$code = '';
while($i < $max_tries && $code == '') {
//generate a random code
$code = gen_code(8);
//add it to codes if it's not already there
//if it is already there then increment the
//repeat counter
if(in_array($code,$codes)) {
$i++;
$code == '';
} //end if
} //end while
if($i == $max_tries) {return 0;}
//write the new code to the file
$handle = fopen($file_name,'a') or die('could not open ' . $file_name . ' for writting');
fwrite($handle,$code . "\n");
fclose($handle);
return $code;
} //end gen_codes
//this function will generate a single alpha
//numeric code that is len characters long
/*string*/ function gen_code($len = 6) {
$code = '';
for($i=0;$i<$len;$i++) {
switch (mt_rand(0,2)) {
case 0:
$code .= chr(mt_rand(65,90));
break;
case 1:
$code .= chr(mt_rand(97,122));
break;
case 2:
$code .= mt_rand(0,9);
} //end switch
} //end for
return $code;
} //end gen_code
?>