Ajax分割上传文件_PHP后台验证文件

一、首先我们先新建两个文件

up_file.html 前台文件 上传文件

move_file.php 后台文件 - 接收并验证文件属性

通过Js将文件分块上传,每次分块大小为1M,通过Ajax 循环上传 - PHP接受文件判断文件是否合法,并上传的服务器

二、编写后台脚本 - 验证文件属性是否合法

<?php
session_start();
Class upfile{

    public function movefile($data,$file){

        if($data["model"] == 1){
             //validatefile 函数是验证文件是否合法
             if($this -> validatefile($file['file']['tmp_name'])){
                $str_end = explode('.',$file['file']['name']);
                $str_end = strtolower(end($str_end)); //获取文件后辍
                $set_path = sha1(strtotime(date("Y-m-d-s",time()))).$str_end; //设置文件地址

                 move_uploaded_file($file['file']['tmp_name'],$set_path); //将文件移动到服务器

                 if(file_exists($set_path)){
                    $_SESSION['path'] = $set_path; //将后台文件路径存入session
                     echo '{"tip":200,"message":"上传成功"}'; 
                 }else{
                     echo'{"tip":201,"message":"上传失败"}';
                 }
             }
        }else if($data["model"] == 2){
            //这里是将以后上传的切片写入第一次切片文件内
            $path = $_SESSION['path'];
            if(file_exists($path)){
                file_put_contents($path,file_get_contents($file['file']['tmp_name']),FILE_APPEND);
                echo '{"tip":200,"message":"上传成功"}';
            }
        }else{
            header("HTTP/1.0 404 Not-Found");
        }


    }


   //验证文件属性 - 这里以音乐文件为例子
   public function validatefile($file){

       $fp = fopen($file,'rb'); //打开文件
       $files = fread($fp,2); //读取文件前两个字节
       fclose($fp);

       $strinfo = unpack("C2chars",$files); //将二进制转为数组
       $typecode = intval($strinfo['chars1'].$strinfo['chars2']);

       // wav mp3 flac
       if($typecode == 8273 || $typecode == 7368 || $typecode == 10276){
         return true;       
      }else{
          return false;
      }

   }

    //脚本入口函数
    public function main($data,$file){

       //防止恶意上传这里设置上传文件密码_非管理禁止上传
       if($_POST['token'] == "UP_FILES_TOKEN"){
           $this -> movefile($data,$file);
       }else{
           echo '{"tip":201,"message":"上传文件密码出错"}';
       }
        
    }
    
}


if(isset($_POST) && isset($_FILES)){
    $upfile = new upfile();

    $upfile -> main($_POST,$_FILES);
}else{
    echo '{"tip":404,"message":"文件参数不存在"}';
}


?>

三、编写前端文件Ajax上传 - 将文件分割每份为1M大小

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.css">
	<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
	<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
	<script src="https://cdn.bootcss.com/popper.js/1.14.7/umd/popper-utils.min.js"></script>
	<script src="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>
	<title>上传文件</title>
</head>
<body>
    <div class = "form">

        <input type = "file" name = "up_file" />
        <input type = "text" name = "token" value="请输入上传密码" />
        <input type = "button" onclick="$(this).upfile(this);" value = "上传" />
        <!--进度条-->
        <div class="progress">
	    <div class="progress-bar progress-bar-striped progress-bar-animated bg-success">0%</div>
        </div>
    </div>
</body>
<script>

(function($){
    var length = 1024 * 1024 * 1; //Music 每次上传的大小
    var totalsize = null; //music 文件大小
    var start = 0; // 每次上传开始的字节
    var end = start + length; // 每次上传的末尾字节
    var fd = new FormData();
    var music_file = null; //保存文件
    var totalPiecess = null;
    $.fn.upfile(obj){
        music_file = obj.files[0];
        totalsize = music_file.size;
        //使用slice分割文件	 
        fd.append('file',music_file.slice(start,end),music_file.name);
	start = end;
        end = start + length; //每次分割完,重新设置数值
        totalPiecess = 100 * start/totalsize;
    }

    function ajax_up(){
        fd.append('token',$('input[name="token"]').val());
	    $.ajax({
		    type:"post",
		    data:fd,
	        url:"http://localhost/move_file.php?model=1",
		    DataType:'jsonp',
		    processData: false,
		    contentType: false,
		    success:function(data){
		         data = eval('('+data+')');
		         if (data.tip == 200) {
			        while(start < totalsize){
			            var fm = new FormData();
			            fm.append('token',fd.get('token'));				 
                        fm.append('file',
                        music_file.slice(start,end),
                        music_file.name);
			            $.ajax({					 
                            type:"post",					 
                            data:fm,
			                async:false,
                            url:"http://localhost/move_file.php?model=2",
			                 DataType:'jsonp',
			                 processData: false,
			                 contentType: false,
			                 success:function(data){
			                     add_fm();
			                 },			 
                             error:function(){						 
                                 console.log('error!');
                             }
			             });
		             }
		             alter("上传成功,点击刷新");
		             setTimeout(location.reload(), 3000);
		         } else {				 
                     alter(data.message);
		         }
	         },
             error:function(err){
		         alter("服务器出错");
	         }
          });
       }

function add_fm(){
	start = end;
	end = start + length;
	totalPiecess = 100 * start/totalsize;
	if (totalPiecess > 100) {totalPiecess = 100} //进度条大于100,设置成100
	$('.progress-bar').attr("style","width:"+totalPiecess+"%");
	$('.progress-bar').html(totalPiecess+"%");
}
})(jQuery);

</script>
</html>

此脚本未测试是否能正常运行,请注意检查哦~

点赞
  1. 小粉批说道:
    Firefox Windows 10