本文目录导读:

PHP 中实现 Gzip 压缩主要有两种场景:输出压缩(压缩发送给浏览器的内容)和 文件压缩(压缩/解压文件或字符串),以下是两种场景的详细实现方法。
输出 Gzip 压缩(压缩 HTTP 响应内容)
这是最常见的需求——压缩 PHP 生成的 HTML、JSON 等输出,减少带宽消耗。
使用 ob_gzhandler(推荐,最简单)
在脚本开始处调用 ob_start('ob_gzhandler'),PHP 会自动判断浏览器是否支持 Gzip 并压缩输出。
<?php
// 开启输出缓冲并启用 Gzip 压缩
ob_start('ob_gzhandler');
// 你正常的代码
echo "<h1>Hello World</h1>";
echo str_repeat("测试内容,用于演示压缩效果。", 100);
// 脚本结束时自动输出并关闭缓冲
ob_end_flush();
优点:一行代码搞定,自动协商压缩级别。
注意:ob_gzhandler 会检查 Accept-Encoding 头,如果浏览器不支持 Gzip 则不会压缩。
手动设置 Gzip 编码(更精细控制)
<?php
// 检查浏览器是否支持 Gzip
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) &&
strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
// 设置响应头
header('Content-Encoding: gzip');
// 开始输出缓冲并压缩
ob_start('ob_gzhandler');
} else {
ob_start();
}
echo "<h1>Hello World</h1>";
if (ob_get_level()) {
ob_end_flush();
}
在 php.ini 或 .htaccess 中全局开启(无需改代码)
php.ini 配置:
zlib.output_compression = On zlib.output_compression_level = 6 ; 1-9,默认 6
Apache .htaccess 配置(需 mod_deflate 或 mod_gzip):
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript application/json
</IfModule>
Nginx 配置(推荐在 Web 服务器层做):
gzip on; gzip_types text/plain text/css application/json application/javascript text/xml;
验证是否生效
用浏览器开发者工具(F12)→ Network → 查看响应头:如果看到 Content-Encoding: gzip 说明成功。
文件/字符串的 Gzip 压缩(非 HTTP 输出)
压缩字符串
<?php
$data = "这是一段需要压缩的字符串,重复很多次。" . str_repeat("A", 1000);
// 压缩
$compressed = gzencode($data, 9); // 级别 1-9,9 最高压缩率
echo "原始大小: " . strlen($data) . "\n";
echo "压缩后大小: " . strlen($compressed) . "\n";
// 解压
$uncompressed = gzdecode($compressed);
echo $uncompressed;
压缩文件
<?php
$source = 'large_file.txt';
$dest = 'large_file.txt.gz';
// 打开源文件(读二进制)
$fp_src = fopen($source, 'rb');
$fp_dest = gzopen($dest, 'wb9'); // 'w' 写入,'b' 二进制,'9' 最高压缩
while (!feof($fp_src)) {
$chunk = fread($fp_src, 8192);
gzwrite($fp_dest, $chunk);
}
fclose($fp_src);
gzclose($fp_dest);
echo "文件压缩完成: " . $dest;
解压 .gz 文件
<?php
$source = 'large_file.txt.gz';
$dest = 'restored_file.txt';
$fp_src = gzopen($source, 'rb');
$fp_dest = fopen($dest, 'wb');
while (!gzeof($fp_src)) {
$chunk = gzread($fp_src, 8192);
fwrite($fp_dest, $chunk);
}
gzclose($fp_src);
fclose($fp_dest);
echo "解压完成";
常用 Gzip 函数速查
| 函数 | 用途 | 对应解压函数 |
|---|---|---|
gzencode(string $data, int $level) |
压缩字符串(标准 gzip 格式) | gzdecode() |
gzcompress(string $data, int $level) |
压缩字符串(zlib 格式) | gzuncompress() |
gzdeflate(string $data, int $level) |
压缩字符串(deflate 格式) | gzinflate() |
gzopen(filename, mode) |
打开 gz 文件 | gzclose() |
gzwrite(resource, string) |
写入 gz 文件 | |
gzread(resource, length) |
读取 gz 文件 | |
gzfile(filename) |
将 gz 文件读入数组 |
区别:
gzencode()生成的格式带 gzip 文件头,浏览器可直接识别gzcompress()生成的 zlib 格式头不同,但压缩率相近gzdeflate()最原始的 deflate 格式(不带头和校验)
检查 PHP 是否支持 Gzip
<?php
if (function_exists('gzencode')) {
echo "Gzip 支持已启用";
} else {
echo "需要安装 zlib 扩展";
}
如果显示未启用,需要安装 zlib:
- Ubuntu/Debian:
sudo apt install php-zlib - CentOS/RHEL:
sudo yum install php-zlib - Windows:在 php.ini 中取消注释
extension=php_zlib.dll
最佳实践建议
- Web 服务器层优先:Nginx/Apache 的 Gzip 配置通常比 PHP 层更高效,建议优先在服务器层开启。
- API 接口:如果服务器层无法开启,可以在 PHP 中使用
ob_start('ob_gzhandler')一行解决。 - 大文件压缩:使用
gzopen/gzwrite方式逐块处理,避免内存溢出。 - 压缩级别:级别 6 通常是速度与压缩率的最佳平衡点,高级别(7-9)收益递减且更耗 CPU。
如果需要更多具体场景的代码示例,可以告诉我你具体要压缩什么类型的数据(JSON API?HTML页面?文件下载?)。