swoole中$request->files为空的首要原因是未启用文件上传解析,必须显式配置'set'中的'enable_upload'=>true、'upload_tmp_dir'(路径需真实存在且可写),并确保php的file_uploads=on及upload_max_filesize/post_max_size足够大。

确认是否触发了文件上传的必要条件
PHP 的 $_FILES(以及 Swoole 中的 $request->files)为空,最常见原因是根本没走文件上传流程。Swoole 不会自动解析非 multipart/form-data 请求体里的二进制数据。
- 检查前端
<form></form>是否设置了enctype="multipart/form-data"—— 缺少这个,浏览器只会把文件名当普通字符串发过去 - 用浏览器 DevTools 的 Network 面板看请求的
Content-Type,必须是类似multipart/form-data; boundary=----WebKitFormBoundary...,而不是application/json或application/x-www-form-urlencoded - Postman 测试时,Body 选项卡要选
form-data,不能选raw或x-www-form-urlencoded
检查 Swoole HTTP Server 是否启用了文件上传解析
Swoole 默认关闭文件上传解析,即使请求格式正确,$request->files 也会始终为空。必须显式启用并配置临时目录。
- 在
Server->set()中添加配置:'enable_upload' => true,否则 Swoole 根本不处理 multipart body - 必须指定
'upload_tmp_dir' => '/tmp'(路径需真实存在、Web 进程有写权限),否则解析失败且静默丢弃 - 如果用了
http_compression => true,某些旧版 Swoole(如 4.8.0 之前)在压缩 + multipart 混用时会解析异常,建议关掉压缩或升级
验证 PHP 层面的限制是否被触发
Swoole 解析完上传数据后,会模拟 PHP 原生行为填充 $request->files,但若底层 PHP 配置拦住了,Swoole 也无能为力。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 检查
php.ini中的file_uploads = On—— Docker 容器或定制镜像常默认关掉 - 确认
upload_max_filesize和post_max_size足够大,比如传 10MB 文件,这两个值都得 ≥ 10M - 注意:Swoole 的
package_max_length也要覆盖整个 multipart body 大小(含边界、字段等),一般设为10 * 1024 * 1024以上 - 错误日志里搜
upload error或max file size exceeded,Swoole 会在解析失败时往 error_log 写提示
调试时直接打印原始请求体和解析结果
别只盯着 $request->files,先确认原始数据是否到达、是否被截断。
- 加一行
var_dump($request->rawcontent());看有没有 multipart 边界和文件内容 —— 如果是空或只有表单字段,说明前端根本没发文件 - 检查
$request->header['content-type']是否含multipart/form-data,且带boundary=参数 - Swoole 4.8+ 可用
$request->getUploadedFiles()替代$request->files,它返回更结构化的对象,出错时会抛异常而非静默空数组 - 临时在
onRequest里加error_log(print_r($request->files, true), 3, '/tmp/swoole_files.log');,绕过 var_dump 截断问题
Swoole 的文件上传不是“开箱即用”,enable_upload、upload_tmp_dir、PHP 的 file_uploads 三者缺一不可,且任意一个权限/路径/大小配置不对,都会导致 $request->files 为空——而它不会报错,只会沉默。










