Dropzonejs + php 实现大文件分段上传

本文介绍了如何结合Dropzonejs和PHP实现大文件的分段上传。首先提到了Dropzonejs的安装和初始化教程,并且提供了前端JS代码示例,接着阐述了后台PHP处理分段上传的逻辑。

关于Dropzone的安装 以及 初始化,大家可参考:https://segmentfault.com/a/1190000004045240 

首先,js的代码:

 

function initDropzone(dropzone_id){
	Dropzone.autoDiscover = false;// 抑制Uncaught Error: Dropzone already attached.错误
	// 文件上传
	var dropzone = new Dropzone('#' + dropzone_id,{
	    previewTemplate: document.querySelector('#preview-template').innerHTML,
        url: "/contributes/fileUpload",
        paramName: "file",
        addRemoveLinks: true,
        dictRemoveFile: '<div class="glyphicon glyphicon-trash" aria-hidden="true" style="color:#00a881;"></div>',
        dictCancelUpload: "<div class=\"glyphicon glyphicon-trash\" aria-hidden=\"true\" style=\"color:#00a881;\"></div>",
        dictMaxFilesExceeded: '最大' + allowedMaxFiles[aspSelected] + '枚の画像をアップロードできます。',
        autoProcessQueue:true,
        uploadMultiple:false, //开启分段上传的话,这个配置项要设为false
        clickable:true,
        maxFiles: 9, //最多可以传多少个文件
        maxFilesize: 4096, // MB
        parallelUploads: 1, // 同时上传多少张
        chunking: true, // 开启分段上传
        chunkSize: 1048576000,//每次分段的size,单位byte,1024*1024*1000=104857600,
        timeout: 300000,
        acceptedFiles: "image/*,.mp4,.MOV,.wmv",
        params: function (files, xhr, chunk) { 
        // 此处拼装分段上传时参数,会伴随每个分段请求post过去
            if (chunk) {
                return {
                    dzUuid: chunk.file.upload.uuid, // 当前上传文件的uuid
                    dzChunkIndex: chunk.index,// 第几个片段
                    dzTotalFileSize: chunk.file.size,// 文件总size
                    dzCurrentChunkSize: chunk.dataBlock.data.size, // 当前片段的size
                    dzTotalChunkCount: chunk.file.upload.totalChunkCount, // 总共分几段上传
                    dzChunkByteOffset: chunk.index * this.options.chunkSize, // 
                    dzChunkSize: this.options.chunkSize,
                    dzFilename: chunk.file.name
                };
            }
        },
        init: function() {
        	this.on("addedfile", function(file) {    
                // 添加文件的时候想进行的操作
            	
            });
        	this.on("removedfile", function(removedfile) {
                // 删除文件时的操作
            });
            this.on("success", function(data) {
                // 一个文件上传成功后的操作
            });
            this.on("error", function(file, message) {
            	alert(message);
                this.removeFile(file);
            });
            this.on("complete", function(file) {
                // 文件上传完成后的操作
            });
            this.on("processing", function(file) {
                
            });
            this.on("uploadprogress", function(progress,p2) {
                
            });
            this.on("totaluploadprogress", function(p1, p2, p3) {

            });
            this.on("sending", function(file) {
                
            });
            this.on("queuecomplete", function(progress) {
                
            });
        }
    });
}

 后台php的

/**
	 * 上传文件
	 * */
public function fileUpload(){
	$this->autoRender = false;
	// 调用开始日志
	$this->saveOperateFileLog(REQUEST_START);	
	if ($this->request->is( "post" )) {
		try {
			$fileArray = array();
			$chunksInfo = $_POST;
			if($chunksInfo){
				$dzUuid = $chunksInfo['dzUuid'];
				$dzChunkIndex = $chunksInfo['dzChunkIndex'];
				$dzTotalChunkCount = $chunksInfo['dzTotalChunkCount'];
				$dzFilename = $chunksInfo['dzFilename'];
				$ext = strrchr($dzFilename,'.');
				$uuid = $dzUuid;
				$moveToPath = TOUKOU_IMG_PATH.$uuid.$dzChunkIndex.$ext;
				if(Environment::isTest()){
					$moveToPath = TEST_TOUKOU_IMG_PATH.$uuid.$dzChunkIndex.$ext;
				}
				move_uploaded_file($_FILES['file']['tmp_name'], $moveToPath);
				// 当是最后一个片段时,合并
				if($dzChunkIndex == ($dzTotalChunkCount - 1)){
					$mergeFile = TOUKOU_IMG_PATH.$uuid.$ext;
					if(Environment::isTest()){
						$mergeFile = TEST_TOUKOU_IMG_PATH.$uuid.$ext;
					}
					$fp = fopen($mergeFile, "ab");
					for($i=0; $i<$dzTotalChunkCount; $i++){
						$chunkFilePath = TOUKOU_IMG_PATH.$uuid.$i.$ext;
						if(Environment::isTest()){
							$chunkFilePath = TEST_TOUKOU_IMG_PATH.$uuid.$i.$ext;
						}
						$handle = fopen($chunkFilePath,"rb");
						fwrite($fp, fread($handle, filesize($chunkFilePath)));
						fclose($handle);
						unset($handle);
						unlink($chunkFilePath);//合并完毕的文件就删除
					}
					fclose($fp);
					unset($fp);
					array_push($fileArray,array(
							'FILE_CD'    =>   Sanitize::html($uuid.$ext)
							,'FILE_NM'    =>    Sanitize::html($_FILES['file']['name'])
					));
				}
			}else{
				$ext = strrchr($_FILES['file']['name'],'.');
				$uuid = $this->uuid();
				$moveToPath = TOUKOU_IMG_PATH.$uuid.$ext;
				if(Environment::isTest()){
					$moveToPath = TEST_TOUKOU_IMG_PATH.$uuid.$ext;
				}
				move_uploaded_file($_FILES['file']['tmp_name'], $moveToPath);
				array_push($fileArray,
					array('FILE_CD'    =>   Sanitize::html($uuid.$ext)
						,'FILE_NM'    =>    Sanitize::html($_FILES['file']['name'])
				));
			}
			$this->renderResponse($this, json_encode($fileArray, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));	
			// 调用结束日志
			$this->saveOperateFileLog(REQUEST_END);
		}catch (Exception $ex){
			// 调用异常日志
			$this->saveOperateFileLog(REQUEST_ERR, $ex->getMessage());
			throw $ex;
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮雨疏桐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值