博客
关于我
php 大文件上传
阅读量:793 次
发布时间:2023-02-27

本文共 3408 字,大约阅读时间需要 11 分钟。

最近项目需要上传大资源视频文件时遇到了麻烦,发现服务端无法直接传大文件,这与PHP的配置有关。以下是详细解释和解决方案:

  • PHP配置分析

    PHP默认的文件上传设置通常会限制文件大小和处理时间。常见的配置参数包括:

    • upload_max_filesize = 2M:限制上传的最大文件大小,默认为2MB。
    • post_max_size = 8M:限制通过POST方法上传的数据总大小,默认为8MB。
    • memory_limit = 128M:限制脚本使用的内存。
    • max_execution_time = 30:限制脚本执行的最大时间,默认为30秒。

    这些参数往往无法满足处理大文件(如视频)的需求,可能导致上传失败或超时。

  • 优化配置建议

    对于需要上传大文件的情况,可以通过以下方式优化PHP配置:

    • max_execution_time:将默认值从30秒增加到800秒,避免因处理大文件而超时。
    • upload_max_filesize:将默认值从2M增加到800M,支持更大的文件上传。
    • post_max_size:将默认值从8M增加到900M,确保可以接收更大的POST数据。
    • max_input_time:将默认值从30秒增加到900秒,适应低速网络环境下的文件上传需求。
    • memory_limit:尽量避免修改,确保不超出服务器内存限制,默认值通常为128M即可。
  • 解决思路

    为了实现大文件上传,推荐使用HTML5的FILE API,避免传统方法中使用Flash等插件的复杂性。以下是详细的实现步骤:

    • 前端部分

      1.监听上传按钮的onchange事件。2.获取文件的FILE对象。3.将文件切割为多个小块,并附加到FormData对象中。4.通过AJAX发送文件到服务器,支持断点续传。5.在文件切割和发送过程中,显示上传进度条,提升用户体验。

    • 后端部分

      1.创建上传文件夹并确保目录存在。2.将上传的文件块移动到临时目录。3.所有文件块上传完成后,合成成一个完整的文件。4.删除临时目录,清理服务器空间。5.返回上传后的文件路径或状态信息。

  • PHP实现代码

    使用类来管理文件上传和合成,确保代码逻辑清晰:

    class Upload {    private $filepath; // 上传目录    private $tmpPath; // PHP文件临时目录    private $blobNum; // 第几个文件块    private $totalBlobNum; // 文件块总数    private $fileName; // 文件名    public function __construct($tmpPath, $blobNum, $totalBlobNum, $fileName) {        $this->tmpPath = $tmpPath;        $this->blobNum = $blobNum;        $this->totalBlobNum = $totalBlobNum;        $this->fileName = $fileName;        $this->moveFile();        $this->fileMerge();    }    // 判断是否是最后一块,进行文件合成并删除文件块    private function fileMerge() {        if ($this->blobNum == $this->totalBlobNum) {            $blob = '';            for ($i = 1; $i <= $this->totalBlobNum; $i++) {                $blob .= file_get_contents($this->filepath.'/'.$this->fileName.'__'.$i);            }            file_put_contents($this->filepath.'/'.$this->fileName, $blob);            $this->deleteFileBlob();        }    }    // 删除文件块    private function deleteFileBlob() {        for ($i = 1; $i <= $this->totalBlobNum; $i++) {            @unlink($this->filepath.'/'.$this->fileName.'__'.$i);        }    }    // 移动文件    private function moveFile() {        $this->touchDir();        $filename = $this->filepath.'/'.$this->fileName.'__'.$this->blobNum;        move_uploaded_file($this->tmpPath, $filename);    }    // 创建上传文件夹    private function touchDir() {        if (!file_exists($this->filepath)) {            return mkdir($this->filepath);        }    }    // API返回数据    public function apiReturn() {        if ($this->blobNum == $this->totalBlobNum) {            if (file_exists($this->filepath.'/'.$this->fileName)) {                $data['code'] = 2;                $data['msg'] = 'success';                $data['file_path'] = $_SERVER['HTTP_HOST'].dirname($_SERVER['DOCUMENT_URI']).$this->filepath.'/'.$this->fileName;                echo json_encode($data);            }        } else {            if (file_exists($this->filepath.'/'.$this->fileName.'__'.$this->blobNum)) {                $data['code'] = 1;                $data['msg'] = 'waiting for all';                $data['file_path'] = '';                echo json_encode($data);            }        }        header('Content-type: application/json');        echo json_encode($data);    }}// 实例化并获取系统变量传参$upload = new Upload($_FILES['file']['tmp_name'], $_POST['blob_num'], $_POST['total_blob_num'], $_POST['file_name']);$upload->apiReturn();
  • DEMO代码说明

    前端部分通过JavaScript实现文件切割和发送,支持断点上传,进度条显示。后端部分使用PHP类管理文件上传和合成,确保大文件处理高效稳定。

  • 通过以上方法,可以有效解决大文件上传问题,优化PHP配置,结合现代技术实现进度显示和断点上传,提升用户体验。

    转载地址:http://hgvfk.baihongyu.com/

    你可能感兴趣的文章
    PAT (Basic Level) Practice 乙级1041-1045
    查看>>
    PAT (Basic Level) Practice 乙级1051-1055
    查看>>
    PAT (Basic Level) Practise - 写出这个数
    查看>>
    PAT 1027 Colors in Mars
    查看>>
    PAT 1127 ZigZagging on a Tree[难]
    查看>>
    PAT 2-07. 素因子分解(20)
    查看>>
    SparkSQL学习03-数据读取与存储
    查看>>
    PAT L2-012. 关于堆的判断
    查看>>
    PAT Spell It Right [非常简单]
    查看>>
    PAT-1044. Shopping in Mars (25)
    查看>>
    PAT-乙级-1040 有几个PAT
    查看>>
    PAT1093 Count PAT's (25)(逻辑题)
    查看>>
    PATA1038题解(需复习)
    查看>>
    Patching Array
    查看>>
    Spring源码学习(二):Spring容器之prepareContext和BeanFactoryPostProcessor的介绍
    查看>>
    PatchMatchStereo可能会需要的Rectification
    查看>>
    Path does not chain with any of the trust anchors
    查看>>
    Path形状获取字符串型变量数据
    查看>>
    PAT甲级——1001 A+B Format (20分)
    查看>>
    Skywalking原理
    查看>>