檔案上傳流程通常為:接收檔案 → 重命名 → 存入資料庫。此時資料庫自增 ID 尚未產生,無法直接作為檔名。需一個「低衝突、長度適中、可追蹤」的命名策略。
| 方法 | 長度 | 衝突機率 | 優點 | 缺點 |
|---|---|---|---|---|
| GUID (com_create_guid) | 36 字元(含連字號) | 極低 | 全域唯一 | 太長,不利 URL/資料庫索引 |
| MD5(time()) | 32 字元 | 低(秒級並發仍衝突) | 可控種子 | 需外部種子,長度固定 32 |
| uniqid() | 13/23 字元 | 低(微秒級) | 長度適中,可加前綴 | 高併發下仍有理論衝突 |
function fast_uuid($suffix_len = 3) {
$base_ts = strtotime('2013-03-21'); // 自訂起始時間,縮減位數
$time = explode(' ', microtime());
$id = ($time[1] - $base_ts) . sprintf('%06u', substr($time[0], 2, 6));
if ($suffix_len > 0) {
$id .= substr(sprintf('%010u', mt_rand()), 0, $suffix_len);
}
return $id;
}
// 輸出範例:29832412631099013
優點:自訂時間基準大幅縮短數字長度;附加隨機數解決同微秒衝突。
function random($len, $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
$hash = '';
$max = strlen($chars) - 1;
for ($i = 0; $i < $len; $i++) $hash .= $chars[mt_rand(0, $max)];
return $hash;
}
$filename = time() . '_' . random(6); // 如 1701123456_aB3f9K
const KEY_CODE = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
function dec2base64($dec, $pad = 0) {
$base = KEY_CODE;
$result = '';
do {
$result = $base[$dec % 64] . $result;
$dec = intval($dec / 64);
} while ($dec > 0);
return $pad ? str_pad($result, $pad, '0', STR_PAD_LEFT) : $result;
}
function base642dec($str) {
$map = array_flip(str_split(KEY_CODE));
$result = 0;
foreach (str_split($str) as $ch) {
$result = $result * 64 + $map[$ch];
}
return $result;
}
// 使用範例
$userId = 12345; // 十進位
$relTime = time() - strtotime('2023-01-01');
$rand = mt_rand(0, 64*64*64 - 1); // 3 位 base64 空間
$filename = dec2base64($userId, 4) . dec2base64($relTime, 4) . dec2base64($rand, 3);
// 例:0X9K_2pQa_7fB
| 演算法 | 10,000 次耗時(秒) | 備註 |
|---|---|---|
| 位元運算法(含二進位轉換) | 0.169 | 支援 16 進位轉 64 進位,適用 MD5 縮短 |
| 純數學取模法 | 0.045 | 速度最快,適合純數字 ID |
uniqid('prefix_', true) 即足夠(23 字元)。