multipart 请求中 $request->input('') 为空是正常现象,因 thinkphp 默认不解析 multipart/form-data,而是依赖 $_post 和 $_files;取字段用 param() 或 post(),取文件必须用 file(),且需确保 php 启用 file_uploads 并避免前端手动设置无 boundary 的 content-type。

为什么 multipart 请求的 $request->input('') 是空的
因为 ThinkPHP 的 input() 默认只解析 application/x-www-form-urlencoded 和 application/json,对 multipart/form-data 请求体不走原始 input 解析路径——它直接跳过 php://input,转而依赖 PHP 自带的 $_POST 和 $_FILES 超全局变量。所以 $request->input('') 返回空字符串或 null 是正常行为,不是你漏写了代码。
$request->param() 拿不到文件字段,但 $_FILES 有数据
这是 multipart 的标准处理机制:$request->param() 只合并 $_GET 和 $_POST(不含文件),而文件信息始终在 $_FILES 中独立存在。TP6 不会把 $_FILES 的键自动塞进 param() 结果里。
- 想取普通字段:用
$request->param('field_name')或$this->request->post('field_name') - 想取文件:必须用
$this->request->file('upload')(单文件)或$this->request->file()(全部) - 别写
$request->input('upload')—— 它永远为空,文件根本不在 input 流里
PHP 配置未启用 file_uploads 导致 $_FILES 全空
即使前端正确发送了 FormData,如果 PHP 环境禁用了文件上传,$_FILES 就是空数组,TP6 的 file() 方法自然也返回 null。这不是框架问题,是底层限制。
- 检查
php.ini:确认file_uploads = On,且upload_max_filesize、post_max_size设置合理(如20M) - 修改后必须重启 Web 服务(Apache/Nginx + PHP-FPM)
- 临时验证:在控制器里加
var_dump($_FILES); die;,看是否真为空
前端发 multipart 时手动设置了 Content-Type
这是最隐蔽的坑:FormData 实例默认不设 Content-Type 头,由浏览器自动添加带 boundary 的 multipart/form-data;一旦你手动设置,比如 headers: {'Content-Type': 'multipart/form-data'},boundary 就丢失,PHP 无法解析,$_POST 和 $_FILES 全为空。
- 前端必须删掉所有手动设置的
Content-Type - 确保
fetch或axios传的是原生FormData实例,不要JSON.stringify()它 - 多文件同名上传(如
photos[])要逐个append('photos', file1)、append('photos', file2),不能一次性传数组
$_FILES 是否真实为空,再排查前端 header 和后端配置,比在 TP 层反复调 input() 有效得多。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











