php实现分片上传
PHP 分片上传实现方法
分片上传(Chunked Upload)是将大文件分割成多个小块进行上传的技术,适用于大文件传输或网络不稳定的场景。以下是PHP实现分片上传的详细方法:
客户端实现(HTML/JavaScript)
使用JavaScript的File API将文件分片:

<input type="file" id="fileInput">
<button onclick="uploadFile()">上传</button>
<script>
function uploadFile() {
const file = document.getElementById('fileInput').files[0];
const chunkSize = 1024 * 1024; // 1MB分片
const totalChunks = Math.ceil(file.size / chunkSize);
for (let i = 0; i < totalChunks; i++) {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('file', chunk);
formData.append('chunkIndex', i);
formData.append('totalChunks', totalChunks);
formData.append('fileName', file.name);
fetch('upload.php', {
method: 'POST',
body: formData
}).then(response => response.json())
.then(data => console.log(data));
}
}
</script>
服务端处理(PHP)
创建upload.php处理分片上传:
<?php
// 确保上传目录存在
$uploadDir = 'uploads/';
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
// 获取上传参数
$fileName = $_POST['fileName'];
$chunkIndex = (int)$_POST['chunkIndex'];
$totalChunks = (int)$_POST['totalChunks'];
// 临时分片文件名
$tempFileName = $uploadDir . $fileName . '.part' . $chunkIndex;
// 移动上传的分片
move_uploaded_file($_FILES['file']['tmp_name'], $tempFileName);
// 检查是否所有分片已上传
$allChunksUploaded = true;
for ($i = 0; $i < $totalChunks; $i++) {
if (!file_exists($uploadDir . $fileName . '.part' . $i)) {
$allChunksUploaded = false;
break;
}
}
// 合并分片
if ($allChunksUploaded) {
$finalFilePath = $uploadDir . $fileName;
$fp = fopen($finalFilePath, 'wb');
for ($i = 0; $i < $totalChunks; $i++) {
$chunkFile = $uploadDir . $fileName . '.part' . $i;
fwrite($fp, file_get_contents($chunkFile));
unlink($chunkFile); // 删除分片文件
}
fclose($fp);
echo json_encode(['status' => 'complete', 'file' => $finalFilePath]);
} else {
echo json_encode(['status' => 'chunk_uploaded', 'chunk' => $chunkIndex]);
}
?>
断点续传实现
为支持断点续传,服务端可记录已上传分片:

// 在合并前检查分片是否存在
if (file_exists($tempFileName)) {
echo json_encode(['status' => 'chunk_exists', 'chunk' => $chunkIndex]);
exit;
}
// 上传完成后记录状态
file_put_contents($uploadDir . $fileName . '.status', json_encode([
'uploaded' => true,
'size' => filesize($finalFilePath)
]));
安全增强措施
增加安全验证:
// 验证文件类型
$allowedTypes = ['image/jpeg', 'image/png'];
if (!in_array($_FILES['file']['type'], $allowedTypes)) {
http_response_code(400);
die('Invalid file type');
}
// 限制文件大小
$maxSize = 100 * 1024 * 1024; // 100MB
if ($_FILES['file']['size'] > $maxSize) {
http_response_code(400);
die('File too large');
}
// 生成唯一文件名防止冲突
$fileExt = pathinfo($fileName, PATHINFO_EXTENSION);
$uniqueName = uniqid() . '.' . $fileExt;
进度跟踪实现
客户端可通过以下方式跟踪进度:
let uploaded = 0;
const progress = document.getElementById('progress');
fetch('upload.php', {
method: 'POST',
body: formData
}).then(response => {
uploaded++;
progress.value = (uploaded / totalChunks) * 100;
return response.json();
});
以上方法实现了完整的PHP分片上传功能,包括分片处理、合并、进度跟踪和安全验证。可根据实际需求调整分片大小和错误处理机制。






