您现在的位置是:群英 > 开发技术 > PHP语言
PHP文件分块上传的脚本如何写
Admin发表于 2022-12-13 10:44:21497 次浏览
关于“PHP文件分块上传的脚本如何写”的知识点有一些人不是很理解,对此小编给大家总结了相关内容,文中的内容简单清晰,易于学习与理解,具有一定的参考学习价值,希望能对大家有所帮助,接下来就跟随小编一起学习一下“PHP文件分块上传的脚本如何写”吧。

目录
  • 一、分块上传流程
  • 二、实现代码
    • HTML
    • JS
    • PHP

我们在上传大文件时,可能会由于服务器的原因导致文件上传失败,文件过大时由于服务器的配置或响应事件过长导致上传文件失败,这时候我们可以将一个大的文件分为若干块,然后分批次上传到服务端,当所有文件块上传完成后再由服务器将各个文件块整合成我们上传的文件

一、分块上传流程

1:由前端js将上传的文件信息进行切割成若干块,然后循环将若干块的文件块上传到服务端

2:服务端接收到文件块信息后保存起来,当所有文件块上传完毕后,将所有上传的文件块整合成文件并保存起来

二、实现代码

HTML

<input type="file" id="file">
<input type="button" id="upload" value="上传">
<input type="button" id="stop" value="停止">
<input type="button" id="restart" value="继续上传">
上传进度:<span id="progress"></span>

JS

//获取节点
var fileForm = document.getElementById("file");
var uploadBtn = document.getElementById('upload');
var stopBtn = document.getElementById('stop');
var restartBtn = document.getElementById('restart');
//定义常量
const LENGTH = 100 * 1024;//每个上传的文件块大小(100KB)
var start = 0;
var end = LENGTH + start;
var blob;
var is_stop = 0;
var blob_num = 1;
var file = null;
var upload_instance = new Upload();
//上传事件
uploadBtn.onclick = function () {
   upload_instance.addFileAndSend(fileForm);
   return false;
}
stopBtn.onclick = function () {
   upload_instance.stop();
   return false;
}
restartBtn.onclick = function () {
   upload_instance.start();
   return false;
}
function Upload() {
    //判断浏览器类型
    if (window.XMLHttpRequest){
        //IE7+, Firefox, Chrome, Opera, Safari
        var xhr=new XMLHttpRequest();
    }else{
        //IE6, IE5
        var xhr=new ActiveXObject("Microsoft.XMLHTTP");
    }
   //上传文件
   this.addFileAndSend = function (that) {
       file = that.files[0];
       blob = cutFile(file);
       //上传
       uploadFile(blob, file);
       blob_num += 1;
   }
   //停止文件上传
   this.stop = function () {
       xhr.abort();
       is_stop = 1;
   }
   this.start = function () {
       uploadFile(blob, file);
       is_stop = 0;
   }
   //切割文件
   function cutFile(file) {
       var file_blob = file.slice(start, end);
       start = end;
       end = start + LENGTH;
       return file_blob;
   };
    //上传文件
    function uploadFile(blob, file) {
        var form_data = new FormData();
        var total_blob_num = Math.ceil(file.size / LENGTH);
        //上传文件信息
        form_data.append('file', blob);
        //上传的第几个文件块
        form_data.append('blob_num', blob_num);
        //总文件块数
        form_data.append('total_blob_num', total_blob_num);
        //文件名称
        form_data.append('file_name', file.name);
        
        
        //上传
        xhr.open('POST', './test.php', false);
        xhr.onreadystatechange = function () {
            //获取上传进度
            if (total_blob_num == 1) {
                progressText = '100%';
            } else {
                progressText = (Math.min(100, (blob_num / total_blob_num) * 100)).toFixed(2) + '%';
            }
            var progress = document.getElementById('progress');
            progress.innerHTML = progressText;
            
            //循环执行上传,直到所有文件块上传完成
            var t = setTimeout(function () {
                if (start < file.size && is_stop == 0) {
                    blob = cutFile(file);
                    uploadFile(blob, file);
                    blob_num += 1;
                } else {
                    //所有文件块上传完成
                }
            }, 1000);
        }
        xhr.send(form_data);
        //每次文件块上传后,清空上传信息
        form_data = "";
    }
}

PHP

上传类

class Upload
{
    /**
     * @var string 上传目录
     */
    private $filepath = './upload'; //上传目录
    /**
     * @var string 块文件临时存储的位置
     */
    private $tmpPath;
    /**
     * @var integer 第几个文件块
     */
    private $blobNum;
    /**
     * @var integer //文件块总数
     */
    private $totalBlobNum;
    /**
     * @var string 上传文件名
     */
    private $fileName;
    public function __construct($tmpPath, $blobNum,$totalBlobNum,$fileName, $filepath = ''){
        if (!empty($filepath)) {
            $this->filepath = $filepath;
        }
        $this->tmpPath = $tmpPath;
        $this->blobNum = $blobNum;
        $this->totalBlobNum = $totalBlobNum;
        $this->fileName = $fileName;
        //保存文件块
        $this->moveFile();
        //保存文件
        $this->fileMerge();
    }
    private function fileMerge(){
        //当文件块都上传后将文件块整合成文件
        if($this->blobNum == $this->totalBlobNum){
            for($i=1; $i<= $this->totalBlobNum; $i++){
                $blob = '';
                $blob = file_get_contents($this->filepath.'/'. $this->fileName.'__'.$i);
                file_put_contents($this->filepath.'/'. $this->fileName, $blob, FILE_APPEND );
                unset($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);
    }
    //上传返回
    public function uploadReturn(){
        if($this->blobNum == $this->totalBlobNum){
            if(file_exists($this->filepath.'/'. $this->fileName)){
                return [
                    'code' => 2,
                    'message' => 'success',
                    'file_path' => 'http://'.$_SERVER['HTTP_HOST'].str_replace('.','',$this->filepath).'/'. $this->fileName,
                    'local_path' => str_replace('.','',$this->filepath).'/'. $this->fileName
                ];
            }
        }
        return [
            'code' => 1,
            'message' => 'waiting',
        ];
    }
    /**
     * 创建目录
     */
    private function touchDir(){
        if(!file_exists($this->filepath)){
            return mkdir($this->filepath);
        }
    }
}

调用上传类

$tmpName = $_FILES['file']['tmp_name'];
$blobNum = $_POST['blob_num'];
$totalBlobNum = $_POST['total_blob_num'];
$fileName = $_POST['file_name'];
$upload = new Upload($tmpName, $blobNum, $totalBlobNum, $fileName);
$data = $upload->uploadReturn();
header('Content-type: application/json');
return json_encode($data);

根据如上步骤就可以实现将文件分成若干块进行上传功能



现在大家对于PHP文件分块上传的脚本如何写的内容应该都清楚了吧,希望大家阅读完这篇文章能有所收获。最后,想要了解更多PHP文件分块上传的脚本如何写的知识,欢迎关注群英网络,群英网络将为大家推送更多相关知识的文章。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: php文件上传
相关信息推荐
2021-11-19 18:06:26 
摘要:这篇文章给大家介绍的是PHP中的return怎样定义方法的返回值,其实不仅是PHP,大部分编程语言的函数或者叫方法,都可以用return来定义方法的返回值。小编觉得挺实用的,因此分享给大家做个参考,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。
2022-04-29 11:58:11 
摘要:给大家带来一篇关于python中Pylint是什么的相关教程文章,内容涉及到Python、python教程等相关内容,更多关于python的内容希望能够帮助到大家。
2021-12-21 17:49:37 
摘要:这篇文章我们来了解C语言编程常见错误,C语言编程错误有很多,这篇就主要介绍未初始化的变量、 数组越界、字符串溢出、 重复释放内存和使用无效的文件指针这五种错误及避免的方法,感兴趣的朋友接下来就跟随小编来了解看看吧!
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部