Unique user_id is enough, you don't need "username".
Problem isn't here, but in count of files (in one folder).
Split them by 1000 in folder (or by 100): take first, second and third symbols of ID string and put in separate dirs:
ID = 10524.jpg
filename = 1/0/5/10524.jpg
If it's hard to write algorithm, you can try this function:
function getStorePath($filename, $base_dir)
{
//file should have extension
$ext_pos = strrpos($filename, '.');
if ($ext_pos===false) return false;
//extension will be sanitized (filtered actually)
$ext = preg_replace("|\W+|", "", substr($filename, $ext_pos+1));
if (empty($ext)) return false;
if (in_array($ext, array('php', 'shtml', 'cgi', 'inc', 'module', 'sh', 'sql', 'class'))) return false;
//filename will be filtered
$filename = preg_replace("|\W+|", "", substr($filename, 0, $ext_pos));
if (empty($filename)) $filename = mt_rand(100000, 999999).round(microtime(true)*1000000);
//let's create path to the file.
//we will take first 3 symbols of filename as names of folders
$d = realpath($base_dir).'/';
//first symbol
$d .= $filename[0].'/';
if (!file_exists($d))
{
$md = mkdir($d, 0755);
if ($md===false && !file_exists($d)) return false;
}
//second symbol
if (isset($filename[1]))
{
$d .= $filename[1].'/';
if (!file_exists($d))
{
$md = mkdir($d, 0755);
if ($md===false && !file_exists($d)) return false;
}
}
//and third symbol
if (isset($filename[2]))
{
$d .= $filename[2].'/';
if (!file_exists($d))
{
$md = mkdir($d, 0755);
if ($md===false && !file_exists($d)) return false;
}
}
if (!file_exists($d.$filename.'.'.$ext)) return $d.$filename.'.'.$ext;
else return false;
}