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

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

相关文章

php实现上传

php实现上传

PHP 文件上传实现 HTML 表单设置 创建一个包含文件上传字段的 HTML 表单,确保表单的 enctype 属性设置为 multipart/form-data,这是文件上传必需的设置。 <…

php 实现上传视频

php 实现上传视频

上传视频的基本流程 在PHP中实现视频上传功能需要处理文件接收、验证、存储等步骤。核心是通过$_FILES超全局变量获取上传的文件信息,结合move_uploaded_file函数完成存储。 创建H…

vue实现图片重新上传

vue实现图片重新上传

实现图片重新上传功能 在Vue中实现图片重新上传功能,通常涉及文件选择、预览、上传和重置等步骤。以下是一个完整的实现方案: 模板部分 <template> <div>…

vue实现上传头像显示

vue实现上传头像显示

Vue 实现上传头像并显示 前端实现(Vue 3 + Element Plus) 模板部分 <template> <div class="avatar-upload">…

php实现多图上传

php实现多图上传

PHP 多图上传实现方法 使用 HTML 表单和 PHP 处理多文件上传需要结合前端表单设计及后端处理逻辑。以下是具体实现方式: 前端表单设计 创建包含多文件上传字段的 HTML 表单,需设置 en…

php 实现视频上传

php 实现视频上传

视频上传的基本实现 在PHP中实现视频上传需要处理文件上传、验证和存储。以下是一个基本的实现方法: 创建HTML表单,设置enctype为multipart/form-data: <form…