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

PHP Base64 編碼檔案二進位流:核心用法、三大應用場景與效能考量

     編輯:PHP 相關知識

前言

base64_encode() 將二進位資料轉為 ASCII 字串,體積膨脹約 33%,但能安全穿越純文字協定(Email、JSON、XML、URL)。本文涵蓋核心 API、串流處理大檔、三大實戰場景與效能替代方案。

核心 API

// 編碼
string base64_encode(string $data): string
// 解碼
string|false base64_decode(string $data, bool $strict = false): string
  • $strict = true:遇到非 Base64 字元直接回傳 false(預設寬鬆模式會忽略)。
  • PHP 8.0+ 解碼失敗拋出 ValueError。

檔案編碼標準流程

function fileToBase64(string $path): string|false {
    if (!is_file($path) || !is_readable($path)) return false;
    $binary = file_get_contents($path); // 適用小檔(< memory_limit)
    return base64_encode($binary);
}

// 大檔串流編碼(避免記憶體爆炸)
function fileToBase64Stream(string $path, int $chunkSize = 8192): Generator {
    $fp = fopen($path, 'rb');
    if (!$fp) return;
    while (!feof($fp)) {
        $chunk = fread($fp, $chunkSize);
        // Base64 需 3 字節一組,串流需自行緩衝殘餘位元組
        yield base64_encode($chunk); // 簡易版:每塊獨立編碼,解碼端需對應處理
    }
    fclose($fp);
}
// 正確串流編碼需實作狀態機,建議用成熟庫(如 symfony/mime)

三大核心應用場景

1. 跨系統 API 傳輸二進位檔案

// 發送端
$payload = [
    'filename' => 'report.pdf',
    'mime'     => 'application/pdf',
    'data'     => base64_encode(file_get_contents('report.pdf')),
];
$ch = curl_init('https://api.partner.com/upload');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
]);
$resp = curl_exec($ch);

// 接收端
$input = json_decode(file_get_contents('php://input'), true);
$binary = base64_decode($input['data']);
file_put_contents("/storage/{$input['filename']}", $binary);

優點:JSON 原生支援、無需 multipart 解析、防火牆友善。
缺點:體積 +33%、CPU 編解碼開銷、無法串流處理超大檔。

2. 將圖片/小檔案內嵌資料庫

// 寫入
$stmt = $pdo->prepare('INSERT INTO avatars (user_id, mime, data_base64) VALUES (?, ?, ?)');
$stmt->execute([$uid, 'image/png', base64_encode(file_get_contents($_FILES['avatar']['tmp_name']))]);

// 讀取並輸出
$row = $pdo->query("SELECT mime, data_base64 FROM avatars WHERE user_id=$uid")->fetch();
header("Content-Type: {$row['mime']}");
echo base64_decode($row['data_base64']);

// 或直接輸出 Data URI(前端 )
echo '';

適用:小圖示、QR Code、簽名檔(< 100KB)。
大檔請存檔案系統/物件存儲,資料庫只存路徑。

3. 簡易授權碼/簽名驗證(非加密,僅編碼)

// 產生授權碼
$payload = json_encode(['uid' => 123, 'exp' => time() + 86400*365, 'features' => ['pro', 'api']]);
$license = base64_encode($payload); // 發給客戶

// 驗證端
$decoded = json_decode(base64_decode($license), true);
if ($decoded['exp'] < time()) exit('Expired');
if (!in_array('pro', $decoded['features'])) exit('Feature not allowed');

警告:Base64 非加密,任何人可解碼竄改。生產環境請用 非對稱簽名:

// 簽名
$privateKey = openssl_pkey_get_private(file_get_contents('private.pem'));
openssl_sign($payload, $signature, $privateKey, OPENSSL_ALGO_SHA256);
$license = base64_encode($payload) . '.' . base64_encode($signature);

// 驗證
[$payloadB64, $sigB64] = explode('.', $license, 2);
$publicKey = openssl_pkey_get_public(file_get_contents('public.pem'));
$valid = openssl_verify($payloadB64, base64_decode($sigB64), $publicKey, OPENSSL_ALGO_SHA256);

效能與記憶體優化

檔案大小建議做法
< 1 MBbase64_encode(file_get_contents($path)) 直覺簡潔
1 MB ~ 100 MB分塊讀取 + 串流編碼(自行緩衝 3 字節對齊)或 symfony/mime
> 100 MB勿用 Base64,改用 multipart/form-data、預簽名 URL、物件存儲 SDK

URL 安全版 Base64(RFC 4648 §5)

function base64url_encode(string $data): string {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode(string $data): string {
    $pad = strlen($data) % 4;
    if ($pad) $data .= str_repeat('=', 4 - $pad);
    return base64_decode(strtr($data, '-_', '+/'));
}
// 用於 JWT、URL 參數、Cookie 值

常見錯誤與排查

  1. 大檔案 OOM:file_get_contents 一次載入整檔 → 改串流或增加 memory_limit。
  2. 解碼失敗回傳空字串:啟用 base64_decode($str, true) 嚴格模式檢查。
  3. 圖片顯示斷裂:Data URI 超過瀏覽器長度限制(IE 32KB,現代瀏覽器較大但不建議超過 100KB)。
  4. 中文檔名亂碼:JSON 傳輸檔名請 rawurlencode 或放入 UTF-8 JSON 字串。

結語

Base64 是「二進位轉文字」的通用膠水,適合小檔案、文字協定傳輸、Data URI 內嵌。大檔案、高併發、安全敏感場景請改用串流上傳、物件存儲、非對稱簽名。記住:Base64 不等於加密,體積 +33%,CPU 有開銷。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved