根本原因是swoole http server的max_package_size限制(默认4mb)被触发,导致请求体未收全即断连,fileupload无法执行;需在config/autoload/server.php的settings中配置'max_package_size' => 100 1024 1024,并同步调整nginx的client_max_body_size及fileupload的max_size。

Hyperf 的 FileUpload 上传大文件失败,根本原因通常不是 FileUpload 组件本身,而是 Swoole HTTP Server 的 max_package_size 限制被触发了 —— 默认仅 4MB,超限后连接直接断开,连请求体都收不全,自然没法走到上传逻辑。
为什么改 max_package_size 才管用?
Hyperf 基于 Swoole HTTP Server,所有 HTTP 请求(包括 multipart/form-data)都先由 Swoole 接收并缓存。Swoole 在解析完整个 HTTP 包前,会校验总包大小是否超过 max_package_size。一旦超限,立刻关闭连接,返回空响应或 400 错误(有时甚至无响应),FileUpload 根本没机会执行。
常见现象包括:
- 前端
fetch或axios报Network Error或ERR_CONNECTION_RESET - Hyperf 日志里完全看不到请求进来的痕迹(
AccessLog和中间件日志均为空) - 用
curl -v测试时卡在Waiting for response后直接断连
在哪里设置 max_package_size?
必须在 Swoole Server 初始化阶段设置,即 config/autoload/server.php 的 settings 数组中,不能在中间件、控制器或 FileUpload 配置里改。
示例配置(支持 100MB 文件):
'settings' => [
'max_package_size' => 100 * 1024 * 1024, // 单位:字节
// 其他 settings...
],
注意:
- 值必须是整数,单位为字节;写成
100 * 1024 * 1024比硬编码104857600更可读且不易出错 - 该配置影响所有 HTTP 请求(不仅是上传),设得过大可能增加内存压力,但对现代服务器影响有限
- 修改后必须重启服务:
php bin/hyperf.php start,热重载不生效
还要同步检查的几个关键点
max_package_size 是前提,但不是唯一条件。以下任一未调优都会导致上传失败:
-
upload_max_filesize和post_max_size(PHP-FPM 场景才需关注;Hyperf 直连 Swoole 时**不经过 PHP ini**,此项可忽略) -
client_max_body_size(Nginx 反向代理时必须同步调整,否则 Nginx 在请求到达 Hyperf 前就拦截了) -
FileUpload的max_size配置(这是应用层校验,单位是字节,例如100 * 1024 * 1024,它只在 Swoole 成功接收后才生效) - 超时设置:大文件上传慢,还需增大
request_timeout(Swoole)和timeout(Nginx)
真正容易被忽略的是:Nginx 的 client_max_body_size 和 Swoole 的 max_package_size 必须一致或前者 ≥ 后者。两者只要有一个卡住,上传就静默失败,而且错误表现几乎一样 —— 看不到日志、没有堆栈、前端只有网络错误。











