首页后端开发PHPPHP文件分块上传的脚本如何写

PHP文件分块上传的脚本如何写

时间2024-03-22 07:35:02发布访客分类PHP浏览1455
导读:关于“PHP文件分块上传的脚本如何写”的知识点有一些人不是很理解,对此小编给大家总结了相关内容,文中的内容简单清晰,易于学习与理解,具有一定的参考学习价值,希望能对大家有所帮助,接下来就跟随小编一起学习一下“PHP文件分块上传的脚本如何写”...
关于“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文件分块上传的脚本如何写的知识,欢迎关注网络,网络将为大家推送更多相关知识的文章。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: PHP文件分块上传的脚本如何写
本文地址: https://pptw.com/jishu/650208.html
你还不会?在PHP里灵活使用观察者模式益处多着呢 Oracle中怎么创建触发器,游标的应用有哪些

游客 回复需填写必要信息