php+plupload+sortable实现多图上传 大视频分片上传、断点续传、缩略图排序

最近在研究做一个多图上传,大视频上传、支持断点续传的功能,发现plupload插件比较符合要求,于是进行了简单研究,有什么不对的地方还望大家指正(新手,第一次写博客。。。)。
主要使用plupload插件(plupload.full.min.js、jquery.plupload.queue.js、jquery.plupload.queue.css、zh_CN.js)、以及Sortable.js插件

效果❤:
1.
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
4.
在这里插入图片描述

1.页面部分

引入css js

<link rel="stylesheet" type="text/css" href="/js/plupload-2.3.6/js/jquery.plupload.queue/css/jquery.plupload.queue.css">
    <script src="/js/jquery.min.js"></script>
    <script src="/js/plupload/plupload.full.min.js"></script>
    <script src="/js/plupload-2.3.6/js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
    <script src="/js/plupload-2.3.6/js/i18n/zh_CN.js"></script>

1.1上传成功后缩略图展示部分样式

<style>
       
    

#pic-list {
        list-style-type: none;
        /*position: absolute;*/
        border: 2px solid #767997;
        padding: 5px;
        display: none;
        width: 315px;
        overflow: hidden;
        /*margin-bottom: 100px;*/
    }
    #pic-list #triangle {
        border: 10px solid #767997;
        border-color: transparent transparent #767997 transparent;
        position: absolute;
        top: -20px;
        left: 5px;
    }
    #pic-list #title {
        padding-bottom: 5px;
    }
    #pic-list #title span {
        font-weight: bold;
    }
    #pic-list #title b {
        float: right;
    }
        #pic-list #title b:hover {
            color: #434664;
        }
        #pic-list #title #hint {
            color: #434664;
            font-size: .7em;
            padding-top: .7em;
        }
        #pic-list li {
            position: relative;
            display: inline-block;
            float: left;
            margin: 5px 5px 0px 0px;
            font-size: 0px; /* 解决换行间隙问题 */
            cursor: move;
        }
        #pic-list li#addBtn {
            box-sizing: border-box;
            width: 100px;
            /*height: 100px;*/
            height: 75px;
            /*line-height: 90px;*/
            line-height: 60px;
            border: 2px dashed #CCC;
            color: #CCC;
            font-size: 80px;
            text-align: center;
            padding-bottom: 30px;
        }
        #pic-list li img {
            box-sizing: border-box;
            width: 100px;
            /*height: 100px;*/
            height: 75px;
            border: 2px dashed #CCC;
        }
        #pic-list li:not(#addBtn):hover {
            filter: alpha(Opacity=50);
            -moz-opacity: 0.5;
            opacity: 0.5;
        }
        #pic-list li#addBtn:hover {
            border-color: #767997;
            color: #767997;
        }
        #pic-list li b{
            display: none;
            position: absolute;
            right: 0px;
            top: 0px;
            color: black;
            font-size: 15px;
            text-align: center;
            cursor: pointer;
        }
        #title b{
            cursor: pointer;
        }
        #pic-list li:not(#addBtn):hover b {
            display: block;
            width: 20px;
            height: 20px;
        }
        #pic-list li:not(#addBtn):hover b:hover {
            background-color: #808080;
        }
      
        #hit{
            height: 18px;
        }
    </style>

1.2html页面核心部分

<div id="uploader">
    <p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<button id="toStop">暂停</button>
<button id="toStart">续传</button>
<!--缩略图展示部分-->
<div>
<ul id="pic-list" style="margin-top: 10px;">
    <span id="triangle"></span>
    <div id="title">
        <b onclick="delall()">X</b>
        <div id="hit"></div>
    </div>
</ul>
</div>

1.3 js部分

<script type="text/javascript">
        $(function() {
            // Initialize the widget when the DOM is ready
            var uploader = $("#uploader").pluploadQueue({
                // General settings
                runtimes: 'html5,flash,silverlight,html4',
                url: "/admin/chunkUpload",//这里替换为你的路径

                // Maximum file size
                max_file_size: '10000mb',

                chunk_size: '20mb',                
                
                // Specify what files to browse for
                filters: [
                    {title: "Image files", extensions: "jpg,gif,png"},
                    {title: "Vedio files", extensions: "mp4,mkv"},
                    {title: "Zip files", extensions: "zip,avi"}
                ],

                // Rename files by clicking on their titles  通过点击文件标题 对文件进行重命名(文件上传前,可以点击文件名称重新编辑文件名)
                rename: true,

                // Sort files
                sortable: true,

                // Enable ability to drag'n'drop files onto the widget (currently only HTML5 supports that)
                dragdrop: true,

                // Views to activate
                views: {
                    list: true,
                    thumbs: true, // Show thumbs
                    active: 'thumbs'
                },

                // Flash settings
                flash_swf_url: 'js/Moxie.swf',

                // Silverlight settings
                silverlight_xap_url: 'js/Moxie.xap'
            });

            uploader.bind('FileUploaded', function(up, file, rt) {
                var data = JSON.parse(rt.response);
              
                if(data.error==0){
                    $('#pic-list').show();
                    var url = data.info.path.replace('./','');
                    //判断是图片还是视频
                    //获取最后一个/的位置
                    var site = url.lastIndexOf(".");
                    //截取最后一个/后的值
                   var tp = url.substring(site + 1, url.length).toLowerCase();
                   var imgarr=['jpg','gif','png'];
                   var videoarr=['mp4','mkv'];
                  if(imgarr.indexOf(tp) > -1){//则包含该元素}){
                      //图片
                    var onepic = '<li><img src="这里替换为你的域名/'+url+'"><b onclick="delimg(this,false)">x</b><input type="hidden" name="" value="这里替换为你的域名/'+url+'"></li>';
                    //$('#title').after(onepic);
                    $('#pic-list').append(onepic);

                  }
                  if(videoarr.indexOf(tp) > -1){

                    //视频
                    var oneVideo='<li><video id="video-div" controls="controls" style="margin-top: 10px;max-width: 400px;width: 100%;max-height:300px;">' +
                        '                        <source src="这里替换为你的域名'+url+'" type="video/mp4" id="video">\n' +
                        '                    </video><b onclick="delimg(this,false)">x</b></li>';
                    //$('#title').after(oneVideo);
                      $('#pic-list').append(oneVideo);
                  }


                    uploader.refresh(); // 重新渲染DOM,避免在添加按钮原位置仍会响应打开文件夹
                }
                else{
                    alert("出错了");
                }
            });


            //当上传队列中某一个文件开始上传后触发。
            uploader.bind('BeforeUpload', function(uploader, file){
                console.log('文件开始上传了');
                //console.dir(file);
            });

            //当使用文件小片上传功能时,每一个小片上传完成后触发
            uploader.bind('ChunkUploaded', function(uploader,file,responseObject){
                console.log('-----当文件上传分片的时候打印 开始----');
                //console.dir(JSON.parse(responseObject['response']));
                console.log('-----当文件上传分片的时候打印 结束---');
            });


            $("#toStop").on('click', function () {
                uploader.stop();
            });

            $("#toStart").on('click', function () {
                uploader.start();
            });
        
        });

        //单张图片删除
        function delimg(o,isConfirm) {
            if(!isConfirm){
                if(confirm("图片删除后不可恢复,确定删除?")) {
                    console.log("delete");
                    var tgname = $(o).prev()[0].tagName
                    console.log($(o).prev()[0].tagName);
                    var src = '';
                    if(tgname == 'IMG'){
                        src =$(o).prev().attr("src");
                    }else{
                        src =$(o).prev().children().attr('src');
                    }

                    delurl = src.substring(18);//注意:此处的imgurl需要根据实际情况修改,需要减去网址域名部分,剩余部门作为参数传递
                    //删除图片路径
                    //imgpath.splice($.inArray(delurl, imgpath), 1);
                    $.post('/admin/uploadImage?get=delimg&imgurl=' + delurl, function (data) {
                        /*optional stuff to do after success */
                        console.log(data);
                        if (data == 1) {
                            if ($("#pic-list").children("li").length == 10) {
                                $("#addBtn").css("display", "block");
                            }
                            $(o).parent().remove();
                          
                        }
                        else {
                            console.log(data);
                        }
                    });
                }
            }else{
                console.log("delete all");
                // /var src = $(o).prev().attr("src");
                var tgname = $(o).prev()[0].tagName
                console.log($(o).prev()[0].tagName);
                var src = '';
                if(tgname == 'IMG'){
                    src =$(o).prev().attr("src");
                }else{
                    src =$(o).prev().children().attr('src');
                }
                delurl = src.substring(18);//注意:此处的imgurl需要根据实际情况修改,需要减去网址域名部分,剩余部门作为参数传递
                //删除图片路径
                imgpath=[];
                $.post('/admin/uploadImage?get=delimg&imgurl=' + delurl, function (data) {
                    /*optional stuff to do after success */
                    console.log(data);
                    if (data == 1) {
                        if ($("#pic-list").children("li").length == 10) {
                            $("#addBtn").css("display", "block");
                        }
                        $(o).parent().remove();
                     
                    }
                    else {
                        console.log(data);
                    }
                });
            }
        }
        // 图片全部删除
        function delall() {
            if(confirm("图片删除后不可恢复,确定删除?")) {
                $("#pic-list").hide();
                $("#pic-list li").children("b").each(function (index, el) {
                    delimg(el,true);
                });
            }

            //显示添加 上传按钮
            $('.plupload_buttons').show();
            $('.plupload_upload_status').hide();
            $('.plupload_total_file_size').html('0 b');
            $('.plupload_total_status').html('0%');
            $('.plupload_upload_status').html('');


        }
        
</script>

2.后台PHP代码

//图片视频上传

    function chunkUpload()
    {
		//封装好的plupload文件上传类,直接使用即可
        require_once __DIR__.'/PluploadHandler.php';

        $ph = new PluploadHandler(array(
            'target_dir' => './uploads/',//上传路径
            'allow_extensions' => 'jpg,jpeg,png,gif,mp4,mov,mkv,zip,avi',//允许上传格式
        ));

        $ph->sendNoCacheHeaders();
        $ph->sendCORSHeaders();

        if ($result = $ph->handleUpload()) {
			//图片上传路径 需做简单修改,这个可以打印出来自己看就明白了
            $result['path']=str_replace('\\','/',$result['path']);            
            die(json_encode(array(
                'error' => 0,
                'info' => $result
            )));
        } else {
            die(json_encode(array(
                'error' => 1,
                'error' => array(
                    'code' => $ph->getErrorCode(),
                    'message' => $ph->getErrorMessage()
                )
            )));
        }
    }
	
	//视频图片删除
    function uploadImage()
    {
        if ($_GET['get'] == 'delimg') {
            $imgsrc = $_GET['imgurl'];
            unlink($imgsrc);
            echo 1;
        }
    }

另:这里把封装好的PluploadHandler.php代码贴出来

<?php


define('PLUPLOAD_MOVE_ERR', 103);
define('PLUPLOAD_INPUT_ERR', 101);
define('PLUPLOAD_OUTPUT_ERR', 102);
define('PLUPLOAD_TMPDIR_ERR', 100);
define('PLUPLOAD_TYPE_ERR', 104);
define('PLUPLOAD_UNKNOWN_ERR', 111);
define('PLUPLOAD_SECURITY_ERR', 105);

define('DS', DIRECTORY_SEPARATOR);

///**
// * Public interface:
// * @method void handleUpload(array $conf)
// * @method string combineChunksFor(string $file_name)
// * @method int getFileSizeFor(string $file_name)
// * @method string getTargetPathFor(string $file_name)
// * @method void sendNoCacheHeaders()
// * @method void sendCorsHeaders()
// * @method int getErrorCode()
// * @method string getErrorMessage()
// *
// */
class PluploadHandler
{
    /**
     * @property array $conf
     */
    private $conf;

    /**
     * Resource containing the reference to the file that we will write to.
     * @property resource $out
     */
    private $out;

    /**
     * In case of the error, will contain error code.
     * @property int [$error=null]
     */
    protected $error = null;


    function __construct($conf = array())
    {
        $this->conf = array_merge(
            array(
                'file_data_name' => 'file',
                'tmp_dir' => ini_get("upload_tmp_dir") . DS . "plupload",
                'target_dir' => false,
                'cleanup' => true,
                'max_file_age' => 5 * 3600, // in hours
                'max_execution_time' => 5 * 60, // in seconds (5 minutes by default)
                'chunk' => isset($_REQUEST['chunk']) ? intval($_REQUEST['chunk']) : 0,
                'chunks' => isset($_REQUEST['chunks']) ? intval($_REQUEST['chunks']) : 0,
                'append_chunks_to_target' => true,
                'combine_chunks_on_complete' => true,
                'file_name' => isset($_REQUEST['name']) ? $_REQUEST['name'] : false,
                'allow_extensions' => false,
                'delay' => 0, // in seconds
                'cb_sanitize_file_name' => array($this, 'sanitize_file_name'),
                'cb_check_file' => false,
                'cb_filesize' => array($this, 'filesize'),
                'error_strings' => array(
                    PLUPLOAD_MOVE_ERR => "Failed to move uploaded file.",
                    PLUPLOAD_INPUT_ERR => "Failed to open input stream.",
                    PLUPLOAD_OUTPUT_ERR => "Failed to open output stream.",
                    PLUPLOAD_TMPDIR_ERR => "Failed to open temp directory.",
                    PLUPLOAD_TYPE_ERR => "File type not allowed.",
                    PLUPLOAD_UNKNOWN_ERR => "Failed due to unknown error.",
                    PLUPLOAD_SECURITY_ERR => "File didn't pass security check."
                ),
                'debug' => false,
                'log_path' => FCPATH."error.log"
            ),
            $conf
        );
    }


    function __destruct()
    {
        $this->reset();
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值