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

确认客户端是否真的发了 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);
}
安全与边界注意事项
直接解压不可信输入有风险,务必控制:
立即学习“PHP免费学习笔记(深入)”;
-
大小限制:zlib 解压可能放大数据(如 ZIP 炸弹),建议加
ini_set('memory_limit', '128M')并检查strlen($raw)上限(如 ≤ 10MB) -
解压失败处理:
gzdecode失败返回false,需判空并返回 400 错误 -
不要混用:若启用
zlib.output_compression=On,它只影响输出,不影响输入解压逻辑



















