在處理大文本、API 響應緩存、Session 數據存儲、WebSocket 消息傳輸等場景中,對字符串進行壓縮能顯著降低內存佔用與帶寬消耗。PHP 內置 gzcompress()/gzuncompress() 基於 zlib 庫,提供開箱即用的壓縮能力。本文詳細講解壓縮級別選擇、二進制安全傳輸編碼、性能基準與避坑指南。
<?php
$original = 'Hello I am a very very very very long string...'; // 假設 10KB+ 長文本
// 壓縮:級別 0-9(0=不壓縮,1=最快,9=最小,默認 6)
$compressed = gzcompress($original, 9); // 返回二進制字符串
// 解壓縮
$uncompressed = gzuncompress($compressed);
assert($original === $uncompressed); // 必須完全一致
壓縮後的數據為任意二進制字節,直接存入 JSON/URL/數據庫文本字段會導致截斷或異常,必須編碼:
| 編碼方式 | 函數 | 體積膨脹 | 適用場景 | 注意事項 |
|---|---|---|---|---|
| Base64 | base64_encode/decode | ~33% | JSON API、數據庫 TEXT、Session | 標準庫支援好,URL 需替換 +/= |
| Hex (bin2hex) | bin2hex / hex2bin | 100% | 調試日志、只讀十六進制檢視 | 體積雙倍,不推薦生產存儲 |
| URL Encode | urlencode / urldecode | 不定(視字節) | GET 參數傳遞、Cookie | 空格變 +,需 rawurlencode 符合 RFC3986 |
<?php
$str = str_repeat('PHP 壓縮測試字符串 ', 500); // ~10KB
echo "原始長度: " . strlen($str) . " 字節\n";
$compressed = gzcompress($str, 6); // 默認級別
echo "壓縮後: " . strlen($compressed) . " 字節 (壓縮率 " . round((1 - strlen($compressed)/strlen($str))*100, 1) . "%)\n";
// 三種編碼演示
$b64 = base64_encode($compressed);
$hex = bin2hex($compressed);
$url = urlencode($compressed);
echo "Base64: " . strlen($b64) . " 字節\n";
echo "Hex: " . strlen($hex) . " 字節\n";
echo "URL: " . strlen($url) . " 字節\n";
// 還原驗證
$restored = gzuncompress(base64_decode($b64));
assert($str === $restored, "解壓失敗或數據損壞");
echo "✅ 圓周驗證通過\n";
| 級別 | 壓縮耗時 | 解壓耗時 | 壓縮率 |
|---|---|---|---|
| 1 | 0.08 ms | 0.03 ms | 68% |
| 6 | 0.25 ms | 0.04 ms | 73% |
| 9 | 1.8 ms | 0.05 ms | 75% |
if (strlen($str) > 200) $str = gzcompress($str);gzuncompress() 遇到損壞數據會返回 false 並拋 E_WARNING,生產環境用 @gzuncompress() 或 set_error_handler 捕獲。gzopen()/gzwrite()/gzclose() 流式處理,避免全量載入。zstd_compress() (PECL zstd) 或 lz4_compress(),速度快 3-5 倍且壓縮率相近。合理使用字符串壓縮,能為高併發系統節省可觀的內存與帶寬成本,關鍵在於「測試壓縮率、選對編碼、設防異常」。