I would use this function, very simple:
/**
* Generates a string with random characters taken from the given string
* of the desided length
*
* @param int $length the resulting string length
* @param string $chars the chars; defaults to all alphanumerics
* @return string the random string
* @author Andrea Baron
*/
function rand_string($length,
$chars = 'qwertyuiopasdfghjklzxcvbnm0123456789') {
$r = '';
$cm = strlen($chars)-1;
for($i=1; $i<=$length; ++$i) {
$r .= $chars[mt_rand(0, $cm)];
}
return $r;
}
then you can do something like this
$used = $db->prepare('SELECT EXISTS(SELECT string FROM table WHERE string = ?)');
do {
$string = rand_string(32);
$used->execute(array($string));
$exists = $used->fetch(PDO::FETCH_NUM);
$used->closeCursor();
} while($exists && $exists[0]);
$ins = PP::$db->prepare('INSERT INTO table SET string=?');
$ins->execute(array($string));
if you use PDO and MySQL; I would set the string field as Primary Key, or a HASH index if on a secondary field; or more concise and, maybe, not as strong:
do {
$string = rand_string(32);
$exists = PP::$db->exec('INSERT INTO a SET string='.PP::$db->quote($string));
} while(!$exists);
this because exec()
returns the number of affected rows on no error, or false if there's an error, in this case a duplicate key value.
Or, as an alternative, you can add a timestamp and forget about checking at all. Like:
$string = rand_string(8).time();
The probability of having a duplicate identifier resets each second, and, with 8 characters, as you see is 1 in 37^8, or 3.5E12.