首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 上傳檔案重命名 6 大策略比較與最佳實踐(含 Base64 縮短技巧)

     編輯:PHP 相關知識

場景痛點

檔案上傳流程通常為:接收檔案 → 重命名 → 存入資料庫。此時資料庫自增 ID 尚未產生,無法直接作為檔名。需一個「低衝突、長度適中、可追蹤」的命名策略。

一、常規方案比較

方法長度衝突機率優點缺點
GUID (com_create_guid)36 字元(含連字號)極低全域唯一太長,不利 URL/資料庫索引
MD5(time())32 字元低(秒級並發仍衝突)可控種子需外部種子,長度固定 32
uniqid()13/23 字元低(微秒級)長度適中,可加前綴高併發下仍有理論衝突

二、進階方案:時間基準 + 隨機數

2.1 fast_uuid(17 位數字)

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

優點:自訂時間基準大幅縮短數字長度;附加隨機數解決同微秒衝突。

2.2 time() + 隨機字串

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

三、終極方案:UserID + 相對時間 + 隨機數 → Base64 編碼

3.1 設計思路

  • UserID:業務層面唯一,轉 Base64 後極短(4 字元可容納 1677 萬)
  • 相對時間:以專案上線日為基準,4~5 字元覆蓋數十年
  • 隨機數:3 字元應對極高併發
  • 總長度:11 字元,兼具可讀性、可追蹤、低衝突

3.2 Base64 編碼演算法(自訂字元表)

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

3.3 效能比較

演算法10,000 次耗時(秒)備註
位元運算法(含二進位轉換)0.169支援 16 進位轉 64 進位,適用 MD5 縮短
純數學取模法0.045速度最快,適合純數字 ID

四、綜合建議

  1. 一般專案:uniqid('prefix_', true) 即足夠(23 字元)。
  2. 高併發/分散式:採用 UserID + 相對時間 + 隨機數 → Base64,長度最短且可反解追蹤。
  3. 需保留 MD5 特性:使用位元運算法將 32 字元 MD5 壓縮為 22 字元 Base64。
  4. 檔案副檔名保留:重命名時務必保留原始副檔名(或透過 MIME 判斷),避免瀏覽器無法識別。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved