当前位置:首页 > PHP

php实现分片上传

2026-02-15 07:22:54PHP

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;

进度跟踪实现

客户端可通过以下方式跟踪进度:

php实现分片上传

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分片上传功能,包括分片处理、合并、进度跟踪和安全验证。可根据实际需求调整分片大小和错误处理机制。

标签: 分片上传
分享给朋友:

相关文章

vue 实现上传

vue 实现上传

Vue 实现文件上传的方法 在 Vue 中实现文件上传可以通过多种方式完成,以下是几种常见的方法: 使用原生 HTML 的 input 元素 通过 HTML 的 input 元素设置 type="f…

vue实现上传功能

vue实现上传功能

实现文件上传功能 在Vue中实现文件上传功能可以通过结合HTML的<input type="file">元素和JavaScript的FormData对象来完成。以下是一个基本的实现方法:…

vue怎么实现视频上传

vue怎么实现视频上传

实现视频上传功能 在Vue中实现视频上传功能通常需要结合HTML5的<input type="file">元素和后端API。以下是实现方法: 前端实现 创建文件上传组件模板: <…

react如何上传本地图片

react如何上传本地图片

上传本地图片的实现方法 在React中上传本地图片通常涉及文件输入处理、预览展示以及上传逻辑。以下是具体实现步骤: 创建文件输入组件 使用HTML的<input type="file">…

react实现照片上传

react实现照片上传

实现照片上传的基本步骤 在React中实现照片上传功能通常涉及前端表单处理、文件选择、预览以及后端API交互。以下是具体实现方法: 创建文件上传表单组件 使用HTML的<input type=…

react实现录制视频上传

react实现录制视频上传

实现视频录制与上传的基本流程 使用React实现视频录制并上传需要结合浏览器提供的媒体API和HTTP上传功能。以下是关键步骤: 获取用户摄像头权限 使用navigator.mediaDevices…