PHP 7.4需手动解压POST中zlib压缩数据:先读取php://input,再根据Content-Encoding头用gzdecode/gzuncompress/gzinflate解压,最后解析JSON或表单数据,并注意大小限制与错误处理。

PHP 7.4 处理 **POST 请求中 zlib 压缩的数据**(比如客户端用 `Content-Encoding: gzip` 或 `deflate` 发送的压缩体),关键不在于“用 POST 调用 zlib”,而在于:**正确识别、解压并读取已压缩的原始请求体**。PHP 默认不会自动解压 `php://input`,需手动处理。 下面分三部分讲清核心要点和实操方法:
确认客户端是否真的发了 zlib 压缩数据
不是所有 POST 都带压缩。先检查请求头:
-
常见压缩头:
Content-Encoding: gzip、Content-Encoding: deflate或Content-Encoding: identity(未压缩) -
务必验证:仅靠
$_POST或file_get_contents('php://input')直接读取,拿到的是二进制乱码——因为没解压 - 调试建议:
var_dump($_SERVER['HTTP_CONTENT_ENCODING'] ?? 'none');
手动解压 php://input 中的 zlib/gzip 数据
PHP 7.4 已内置 zlib 扩展(默认启用),可用以下函数解压:
-
gzdecode($data)→ 解 gzip(含 zlib header + deflate body) -
gzuncompress($data)→ 解纯 deflate 数据(无 zlib header) -
gzinflate($data)→ 解 raw deflate(最底层,常用于Content-Encoding: deflate场景)
推荐写法(兼容 gzip/deflate):
php://input,且不能同时用 $_POST,否则流已耗尽)$raw = file_get_contents('php://input');
$encoding = $_SERVER['HTTP_CONTENT_ENCODING'] ?? '';
if ($encoding === 'gzip') {
$body = gzdecode($raw);
} elseif ($encoding === 'deflate') {
// 尝试两种 deflate 解法(RFC 兼容性差异)
$body = @gzuncompress($raw) ?: @gzinflate($raw);
} else {
$body = $raw; // 未压缩
}
// 现在 $body 是解压后的原始数据,可 json_decode / parse_str 等
if (stripos($contentType, 'application/json') !== false) {
$data = json_decode($body, true);
} elseif (stripos($contentType, 'application/x-www-form-urlencoded') !== false) {
parse_str($body, $data);
}
安全与边界注意事项
直接解压不可信输入有风险,务必控制:
-
大小限制:zlib 解压可能放大数据(如 ZIP 炸弹),建议加
ini_set('memory_limit', '128M')并检查strlen($raw)上限(如 ≤ 10MB) -
解压失败处理:
gzdecode失败返回false,需判空并返回 400 错误 -
不要混用:若启用
zlib.output_compression=On,它只影响输出,不影响输入解压逻辑
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











