plupload在thinkphp中“上传成功但文件没保存”的根本原因是其分片上传机制与thinkphp默认的$_files接收逻辑不兼容,必须手动接管分片接收、临时存储、合并及md5校验。

Plupload 在 ThinkPHP 中为什么总卡在“上传成功但文件没保存”
根本原因是 Plupload 默认走的是纯前端分片上传流程,而 ThinkPHP 的 $_FILES 只接收传统表单提交的完整文件——分片上传时后端根本收不到 $_FILES,自然不会触发 ThinkPHP 自带的文件上传逻辑。
必须手动接管分片上传的合并与校验。常见错误现象包括:UploadFile::upload() 返回 false、$_FILES 为空、浏览器控制台报 500 但日志无记录(其实是没进上传方法)。
- Plupload 发送的是
multipart/form-data分片请求,每个分片带chunk和chunks参数,ThinkPHP 默认路由和控制器不识别这些字段 - 不能直接用
$this->upload()->upload(),得改用$_POST+$_FILES原生处理,再调用move_uploaded_file() - ThinkPHP 5.1+ 的
think\File类不支持分片拼接,必须自己写合并逻辑
ThinkPHP 后端如何正确接收并合并 Plupload 分片
核心是绕过框架上传封装,用原生 PHP 处理 $_FILES['file'] 并按 $_POST['chunk'] 和 $_POST['chunks'] 拼接临时文件。关键点在于:分片必须存到可读写的临时目录,且命名要带唯一标识(如 $_POST['name'] . '_' . $_POST['chunk']),否则多用户并发上传会覆盖。
- 先检查是否为分片上传:
isset($_POST['chunk']) && isset($_POST['chunks']) - 分片临时路径建议用
RUNTIME_PATH . 'upload_tmp/' . md5($_POST['name']) . '/',避免冲突 - 合并完成后务必校验最终文件的
md5_file()是否与前端传来的$_POST['md5']一致(Plupload 支持开启此选项) - ThinkPHP 的
Request::instance()->file()在分片场景下返回空,别依赖它
if (isset($_POST['chunk'])) {
$tmpDir = RUNTIME_PATH . 'upload_tmp/' . md5($_POST['name']) . '/';
@mkdir($tmpDir, 0755, true);
move_uploaded_file($_FILES['file']['tmp_name'], $tmpDir . $_POST['chunk']);
exit('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
}
Plupload 前端配置哪些参数直接影响 ThinkPHP 后端能否解析
不是所有 Plupload 配置都兼容 ThinkPHP 路由和参数解析方式。比如 multipart_params 必须扁平化,不能嵌套对象;url 必须指向一个明确的控制器方法,且该方法不能启用 CSRF 验证(否则 400 Bad Request)。
-
url设为'{:url("Upload/chunk")}'(TP5)或'/index.php?s=/Upload/chunk'(TP6),确保能进对应 action -
multipart_params只放字符串值,例如{'token': 'xxx', 'type': 'avatar'},不要传函数或数组 - 必须设
chunk_size: '1mb',且与后端分片合并逻辑中的块大小严格一致,否则最后一片可能被忽略 - 禁用
send_chunk_number(默认 false),ThinkPHP 不需要它;但要确保required_features: ['html5'],避免降级到 iframe 导致参数丢失
大文件上传时 ThinkPHP 的 PHP 配置和 Nginx 限制怎么调
Plupload 分片本身能绕过 upload_max_filesize,但单个分片仍受限制;而且 Nginx 默认 1MB body 上限会直接拦截分片请求,返回 413。这不是代码问题,是服务器层拦死的。
- PHP 中
upload_max_filesize和post_max_size只需设为略大于单个分片(如2M),不是整个文件大小 - Nginx 必须加
client_max_body_size 100m;到 server 或 location 块,否则分片请求进不了 PHP - ThinkPHP 的
max_execution_time默认 30 秒不够,大文件合并可能超时,建议在上传 action 开头加set_time_limit(300) - 如果用 Swoole 或 RoadRunner,注意它们对
$_FILES的处理更严格,部分版本不支持分片上传的 multipart 解析
真正麻烦的从来不是 Plupload 怎么配,而是分片上传路径上每层(Nginx → PHP → ThinkPHP → 你写的合并逻辑)都有自己的“脾气”,漏掉任意一环,文件就消失在某个中间态里。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











