I need to generate unique filenames for uploaded files. I store the names in a database and when generating a filename check to make sure it's unique. I know there are a lot of questions on this subject on here, but what I'm trying to understand is why my script isn't working.
Her's my code for getting a filename and checking that it is unique:
do {
$newName = generateRandomString(10, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
$stmt = $this->db->prepare('SELECT id FROM images WHERE file_name = :newName');
makeQuery($stmt, array(':newName' => $newName));
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
} while(!empty($row));
Where generateRandomString()
is:
function generateRandomString($length, $characters) {
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
return $randomString;
}
Now, when I run this with about 30,000 filenames in my database, it takes anywhere from a few seconds to literally a few minutes to return a filename.
With as many characters as I'm using in the filenames (0-9a-zA-Z) and with a length of 10, there should be a HUGE number of potential filenames (about 107 billion if I calculated it right). It doesn't seem like there should be any collisions at all, least of all the number I'm getting (an XDebug profile snapshot I analyzed said generateRandomString()
ran over 100,000 times before returning!).
Why isn't this working and what can I do to fix it?
EDIT: Oops, I misinterpreted the xdebug data. It didn't take 100,000 function calls, it took 123,502 milliseconds (so time, not function calls).