laravel webupload实现分片上传文件及分片上传原理

分片实现原理:

把一个大文件分成若干小文件,依次上传服务器后,在服务器进行文件合并。

下面直接上代码:

5ae0ab00af7a2.png

laravel filesystems.php配置文件

'local' => [
    'driver' => 'local',  #文件保存目录
    //'root' => storage_path('app'),
    'root' => public_path('uploads'),
],
'tmp' => [        #缓存文件保存目录
    'driver' => 'local',
    //'root' => storage_path('app'),
    'root' => public_path('uploads/tmp'),
],

html代码:

 
<html>

<body>
<script src="http://www.jq22.com/jquery/jquery-2.1.1.js"></script>
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="{{asset('admin/js/plugins/webuploader/webuploader.css')}}">
<!--引入JS-->
<script type="text/javascript" src="{{asset('admin/js/plugins/webuploader/webuploader.js')}}"></script>

<link rel="shortcut icon" href="favicon.ico"> <link href="{{asset('admin/css/bootstrap.min.css?v=3.3.6')}}" rel="stylesheet">
<link href="{{asset('admin/css/font-awesome.css?v=4.4.0')}}" rel="stylesheet">
<link href="{{asset('admin/css/plugins/bootstrap-table/bootstrap-table.min.css')}}" rel="stylesheet">
<script src="{{asset('admin/js/bootstrap.min.js?v=3.3.6')}}"></script>

<script>
$(document).ready(function(){
    var uploader = WebUploader.create({

        // swf文件路径
        swf: "{{asset('admin/js/plugins/webuploader/Uploader.swf')}}",

        // 文件接收服务端。
        server: "{{url('upload')}}",

        // 选择文件的按钮。可选。
        // 内部根据当前运行是创建,可能是input元素,也可能是flash.
        pick: '#picker',

        // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
        resize: false,
        formData: {
            // 这里的token是外部生成的长期有效的,如果把token写死,是可以上传的。
            _token:'{{csrf_token()}}'
            // 我想上传时再请求服务器返回token,改怎么做呢?反复尝试而不得。谢谢大家了!
            //uptoken_url: '127.0.0.1:8080/examples/upload_token.php'
        },
        // 开起分片上传。
        chunked: true,
        chunkSize:30*1024*1024,
        threads: 1,//上传并发数
        // accept: {
        //     extensions: 'gif,jpg,jpeg,bmp,png,rar,zip,mp4,mp3',
        // }
    });

    // 当有文件被添加进队列的时候
    uploader.on( 'fileQueued', function( file ) {
        var $list = $("#thelist");
        $list.append( '<div id="' + file.id + '" class="item">' +
            '<h4 class="info">' + file.name + '</h4>' +
            '<p class="state">等待上传...</p>' +
            '</div>' );
    });

    // 文件上传过程中创建进度条实时显示。
    uploader.on( 'uploadProgress', function( file, percentage ) {
        var $li = $( '#'+file.id ),
            $percent = $li.find('.progress .progress-bar');

        // 避免重复创建
        if ( !$percent.length ) {
            $percent = $('<div class="progress progress-striped active">' +
                '<div class="progress-bar" role="progressbar" style="width: 0%">' +
                '</div>' +
                '</div>').appendTo( $li ).find('.progress-bar');
        }

        $li.find('p.state').text('上传中');

        $percent.css( 'width', percentage * 100 + '%' );
    });

    uploader.on( 'uploadSuccess', function( file ) {
        $( '#'+file.id ).find('p.state').text('已上传');
    });

    uploader.on( 'uploadError', function( file ) {
        $( '#'+file.id ).find('p.state').text('上传出错');
    });

    uploader.on( 'uploadComplete', function( file ) {
        $( '#'+file.id ).find('.progress').fadeOut();
    });

    $("#ctlBtn").click(function(){
        uploader.retry();;
    });
});
</script>
</body>
    <form action="{{url('upload')}}" method="post" enctype="multipart/form-data">
        <input type="hidden" name="_token" value="{{ csrf_token() }}">
        {{--<input type="file" name="test">--}}

        <div id="uploader" class="wu-example">
            <!--用来存放文件信息-->
            <div id="thelist" class="uploader-list"></div>
            <div class="btns">
                <div id="picker">选择文件</div>
                <button id="ctlBtn" class="btn btn-default" type="button">开始上传</button>
            </div>
        </div>

        {{--<input type="submit">--}}
    </form>
</html>

php上传 及 打开页面代码:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Redis;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;


class TestController extends Controller
{

    public function test(){
        return View('welcome');
    }

    public function upload(){
        $num = Input::get('chunk',0);
        $count = Input::get('chunks',0);
        $file = Input::file('file');
        //获取原文件名
        $originalName = $file->getClientOriginalName();
        //扩展名
        $ext = $file->getClientOriginalExtension();
        //文件类型
        $type = $file->getClientMimeType();
        //临时绝对路径
        $realPath = $file->getRealPath();
        if($num == $count){
            //直接保存
            $filename = date('Y-m-d-H-i-S').'-'.uniqid().'-.'.$ext;
            $bool = Storage::disk('local')->put($filename, file_get_contents($realPath));
        }else{
            //分片临时文件名
            $filename = md5($originalName).'-'.($num+1).'.tmp';
            //上传目录
            $path_name = 'uploads/tmp/'.$filename;
            //保存临时文件
            $bool = Storage::disk('tmp')->put($filename, file_get_contents($realPath));
            //当分片上传完时 合并
            if(($num+1) == $count){
                //最后合成后的名字及路径
                $files_names = 'uploads/'.date("YmdHis",time()).rand(100000,999999).'.'.$ext;
                //打开文件
                $fp = fopen($files_names,"ab");
                //循环读取临时文件,写入最终文件
                for($i=0;$i<$count;$i++){
                    //临时文件路径及名称
                    $tmp_files = 'uploads/tmp/'.md5($originalName).'-'.($i+1).'.tmp';
                    //打开临时文件
                    $handle = fopen($tmp_files,"rb");
                    //读取临时文件 写入最终文件
                    fwrite($fp,fread($handle,filesize($tmp_files)));
                    //关闭句柄 不关闭删除文件会出现没有权限
                    fclose($handle);
                    //删除临时文件
                    unlink($tmp_files);
                }
                //关闭句柄
                fclose($fp);
            }
        }



    }
}

laravel 路由代码:

Route::get('/test',"TestController@test");
Route::post('/upload',"TestController@upload");




ok  试试吧!

喜欢(3)

评论 抢沙发

表情