Plupload+PHP大文件分片上传异常:文件无法正常合并求助
排查与解决Plupload分片上传大文件合并问题
核心问题分析
小文件上传正常,大文件分片后生成无格式临时文件,大概率是分片合并逻辑缺失或错误,或是未将合并后的临时文件重命名为原文件(含后缀)。
常见问题排查与修复
1. 确认分片标识与顺序传递
Plupload会自动传递chunk(当前分片索引)、chunks(总分片数)、name(原文件名)等参数,服务器端必须基于唯一标识(比如结合name+上传会话ID,或生成的文件哈希)归集分片:
- 确保
upload.php中正确接收chunk、chunks、name参数 - 为每个待合并的文件创建独立临时目录或用唯一前缀存储分片,避免不同文件的分片混淆
2. 修复分片合并逻辑
服务器端需在收到最后一个分片时,按顺序拼接所有分片,示例逻辑如下:
$targetDir = 'uploads/temp'; $fileName = $_POST['name']; $chunk = isset($_POST['chunk']) ? intval($_POST['chunk']) : 0; $chunks = isset($_POST['chunks']) ? intval($_POST['chunks']) : 1; // 生成唯一临时分片前缀,避免文件冲突 $tempPrefix = $targetDir . '/' . md5($fileName . $_SERVER['REMOTE_ADDR']); // 写入当前分片 $out = fopen($tempPrefix . '_' . $chunk, 'wb'); if ($out) { $in = fopen($_FILES['file']['tmp_name'], 'rb'); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } fclose($in); fclose($out); } // 最后一个分片触发合并 if ($chunk == $chunks - 1) { $finalFile = 'uploads/' . $fileName; $out = fopen($finalFile, 'wb'); if ($out) { for ($i = 0; $i < $chunks; $i++) { $in = fopen($tempPrefix . '_' . $i, 'rb'); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } fclose($in); unlink($tempPrefix . '_' . $i); // 删除临时分片 } } fclose($out); rmdir($targetDir); // 清理临时目录(若为空) } }
3. 确保保留原文件名与后缀
- 检查
upload.php是否直接使用了随机临时文件名(如file_631c9212682f7)作为最终文件名,需替换为$_POST['name']中的原文件名(包含后缀) - 合并完成后必须将临时文件重命名为原文件的完整名称,比如把
file_631c9212682f7改为travel.mp4或backup.zip
4. 检查文件权限与写入完整性
- 确保服务器的
uploads及临时目录有可写权限(可设置为755,根据服务器配置调整) - 合并时验证每个分片的文件大小是否符合预期,避免分片丢失或写入不完整
5. 验证Plupload前端配置
确保前端开启分片功能并正确配置参数:
var uploader = new plupload.Uploader({ runtimes: 'html5,flash,silverlight,html4', browse_button: 'pickfiles', container: 'container', url: 'upload.php', chunk_size: '10mb', // 按需设置分片大小 unique_names: false, // 若开启此选项,需在服务端维护随机名与原文件名的映射 // ...其他配置 });
内容的提问来源于stack exchange,提问作者Sina Ghoshuni
相关产品推荐
相关产品推荐

