Thinkphp5+plupload实现的图片上传功能示例【支持实时预览】


Posted in PHP onMay 08, 2019

本文实例讲述了Thinkphp5+plupload实现支持实时预览的图片上传功能。分享给大家供大家参考,具体如下:

今天和大家分享一个国外的图片上传插件,这个插件支持分片上传大文件。其中著名的七牛云平台的jssdk就使用了puupload插件,可见这个插件还是相当牛叉的。

这个插件不仅仅支持图片上传,还支持大多数文件的上传,例如视频文件,音频文件,word文件等等,而且大文件都采用分片上传的机制。

Plupload有以下功能和特点:

1、拥有多种上传方式:HTML5、flash、silverlight以及传统的<input type=”file” />。Plupload会自动侦测当前的环境,选择最合适的上传方式,并且会优先使用HTML5的方式。所以你完全不用去操心当前的浏览器支持哪些上传方式,Plupload会自动为你选择最合适的方式。

2、支持以拖拽的方式来选取要上传的文件

3、支持在前端压缩图片,即在图片文件还未上传之前就对它进行压缩

4、可以直接读取原生的文件数据,这样的好处就是例如可以在图片文件还未上传之前就能把它显示在页面上预览

5、支持把大文件切割成小片进行上传,因为有些浏览器对很大的文件比如几G的一些文件无法上传。

下面就介绍一个tp5整合plupload图片上传插件的小案例,希望给大家带来一点小帮助。

一、案例目录结构

Thinkphp5+plupload实现的图片上传功能示例【支持实时预览】

二、Index.php控制器方法

<?php
namespace app\index\controller;
use think\Controller;
use think\Db;
class Index extends Controller{
  public function index(){
    $rootUrl = $this->request->root(true); //ROOT域名
    $rootUrl = explode('index.php',$rootUrl)[0];
    //模板资源变量分配
    foreach (config('TMPL_PARSE_STRING') as $key => $value) {
      $this->view->assign('_'.$key,$rootUrl.$value);
    }
    return $this->fetch();
  }
  //图片上传方法
  public function upload_images(){
    if($this->request->isPost()){
      //接收参数
      $images = $this->request->file('file');
      //计算md5和sha1散列值,TODO::作用避免文件重复上传
      $md5 = $images->hash('md5');
      $sha1= $images->hash('sha1');
      //判断图片文件是否已经上传
      $img = Db::name('picture')->where(['md5'=>$md5,'sha1'=>$sha1])->find();//我这里是将图片存入数据库,防止重复上传
      if(!empty($img)){
        return json(['status'=>1,'msg'=>'上传成功','data'=>['img_id'=>$img['id'],'img_url'=>$this->request->root(true).'/'.$img['path']]]);
      }else{
        // 移动到框架应用根目录/public/uploads/picture/目录下
        $imgPath = 'public' . DS . 'uploads' . DS . 'picture';
        $info = $images->move(ROOT_PATH . $imgPath);
        $path = 'public/uploads/picture/'.date('Ymd',time()).'/'.$info->getFilename();
        $data = [
          'path' => $path ,
          'md5' => $md5 ,
          'sha1' => $sha1 ,
          'status' => 1 ,
          'create_time' => time() ,
        ];
        if($img_id=Db::name('picture')->insertGetId($data)){
          return json(['status'=>1,'msg'=>'上传成功','data'=>['img_id'=>$img_id,'img_url'=>$this->request->root(true).'/'.$path]]);
        }else{
          return json(['status'=>0,'msg'=>'写入数据库失败']);
        }
      }
    }else{
      return ['status'=>0,'msg'=>'非法请求!'];
    }
  }
}

三、index.html页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>tp5+plupload图片上传</title>
</head>
<body>
<!-- production -->
<!--<script type="text/javascript" src="./plupload.full.min.js"></script>-->
<!-- debug-->
<script type="text/javascript" src="{$_plupload}/moxie.js"></script>
<script type="text/javascript" src="{$_plupload}/plupload.dev.js"></script>
<script type="text/javascript" src="{$_plupload}/jquery.min.js"></script>
<style>
  ul{
    list-style:none;
  }
  #file-list {overflow: hidden;padding-left: initial;}
  #file-list li {
    width:160px;
    float: left;
    height:200px;
    position: relative;
    height: inherit;
    margin-bottom: inherit;
  }
  #file-list li a {
    width:150px;
    height:150px;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    margin:0 auto;
    border:1px solid #ccc;
    padding: 5px 5px 5px 5px;
  }
  .close{
    background-image: url("{$_plupload}/close.png");
    width: 30px;
    height: 30px;
    background-size: contain;
    position: absolute;
    right: 2%;
    top: 0;
  }
  #file-list li a img {max-width:100%;max-height: 100%;}
  .progress{
    position: absolute;
    background-color: rgba(4, 4, 4, 0.53);
    color: #fff;
    padding: 3px 3px 3px 3px;
    border-radius: 10%;
  }
</style>
<input type="hidden" id="images_upload" name="images" value=""/>
<div id="container">
  <button class="btn btn-primary" type="button" id="pickfiles" style="height: 30px;line-height: 8px;">选择图片</button>
  <button class="btn btn-primary" type="button" id="uploadfiles" style="display: none">开始上传</button>
  <ul id="file-list">
  </ul>
</div>
<script type="text/javascript">
  //调用例子
  var uploader = new plupload.Uploader({
    runtimes : 'html5,flash,silverlight,html4',//上传方式顺序优先级
    browse_button : 'pickfiles',//选择图片按钮id
    container: document.getElementById('container'),//容器
    url : "{:url('Index/upload_images')}",//服务器接口地址
    flash_swf_url : "{$_plupload}/Moxie.swf",
    silverlight_xap_url : "{$_plupload}/Moxie.xap",
    multi_selection: true,//false为单图上传,true为多图上传
    filters : {
      max_file_size : '100mb',//限制文件上传大小
      mime_types: [
        {title : "Image files", extensions : "jpg,gif,png"},//限制文件上传格式
      ]
    },
    init: {
      //init事件发生后触发
      PostInit: function() {
        //document.getElementById('filelist').innerHTML = '';
        document.getElementById('uploadfiles').onclick = function() {
          uploader.start();
          return false;
        };
      },
      FilesAdded: function(up, files) {//文件选择之后的触发的方法
        var len = len = files.length;
        for(var i = 0; i<len; i++){
          var file_name = files[i].name; //文件名
          var file_size = files[i].size;//文件大小
          //构造html来更新UI
          //var html = '<li id="file-' + files[i].id +'"><p class="file-name">' + file_name + '(' + plupload.formatSize(file_size) + ')' + '</p><p class="progress"></p></li>';
          var html = '<li id="file-' + files[i].id +'"><span class="close"></span></li>';
          $(html).appendTo('#file-list');
          !function(i){
            previewImage(files[i],function(imgsrc){
              $('#file-'+files[i].id).append('<a><img src="'+ imgsrc +'" /><span class="progress">12</span></a>');
            })
          }(i);
          $("#uploadfiles").trigger('click');
        }
        /*plupload.each(files, function(file) {
         document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
         });*/
      },
      UploadProgress: function(up, file) {//上传过程中调用的方法
        //document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
        $('#file-'+file.id +" .progress").html(file.percent + "%");
      },
      FileUploaded : function (up,file,res) {//文件上传完成后
        console.log(res.response);
        var data = JSON.parse(res.response).data;
        $('#file-'+file.id).children('.close').attr('img_id',data.img_id);
        var img = $("#images_upload");
        var str = img.val();
        if(str == ''){
          str = data.img_id;
        }else{
          str += ','+data.img_id;
        }
        img.val(str);
      },
      Error: function(up, err) {
        //document.getElementById('console').appendChild(document.createTextNode("\nError #" + err.code + ": " + err.message));
      }
    }
  });
  //plupload中为我们提供了mOxie对象
  //有关mOxie的介绍和说明请看:https://github.com/moxiecode/moxie/wiki/API
  //file为plupload事件监听函数参数中的file对象,callback为预览图片准备完成的回调函数
  function previewImage(file,callback){
    if(!file || !/image\//.test(file.type)) return; //确保文件是图片
    if(file.type=='image/gif'){ //gif使用FileReader进行预览,因为mOxie.Image只支持jpg和png
      var gif = new moxie.file.FileReader();
      gif.onload = function(){
        callback(gif.result);
        gif.destroy();
        gif = null;
      };
      gif.readAsDataURL(file.getSource());
    }else{
      var image = new moxie.image.Image();
      image.onload = function() {
        image.downsize( 150, 150 );//先压缩一下要预览的图片,宽300,高300
        var imgsrc = image.type=='image/jpeg' ? image.getAsDataURL('image/jpeg',80) : image.getAsDataURL(); //得到图片src,实质为一个base64编码的数据
        callback && callback(imgsrc); //callback传入的参数为预览图片的url
        image.destroy();
        image = null;
      };
      image.load( file.getSource() );
    }
  }
  uploader.init();
  //移除图片
  $("#file-list").on('click',".close",function(){
    var img_id = $(this).attr("img_id");
    var img = $("#images_upload");
    var items=img.val().split(",");
    var index = items.indexOf(img_id);
    items.splice(index,1);//删除元素
    img.val(items.join(','));
    $(this).parent().remove();
  });
</script>
</body>
</html>

Thinkphp5+plupload实现的图片上传功能示例【支持实时预览】

如果想研究插件源码的朋友,可以看这个文件,其中大部分都已经注释了。

Thinkphp5+plupload实现的图片上传功能示例【支持实时预览】

最终效果就是这样了。

 

Thinkphp5+plupload实现的图片上传功能示例【支持实时预览】

如果对tp5不太熟悉的朋友,建议直接配置虚拟域名,将项目目录绑定到/tp5/public/目录。

案例源码:https://github.com/BlueSimle/thinkphp5-plupload  (如果对你有帮助,请给个star哦。如果有什么疑问,请留言)

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
PHP iconv 函数转gb2312的bug解决方法
Oct 11 PHP
php获得url参数中具有&amp;的值的方法
Mar 05 PHP
php实现mysql事务处理的方法
Dec 25 PHP
php按字符无乱码截取中文的方法
Mar 27 PHP
php通过exif_read_data函数获取图片的exif信息
May 21 PHP
php获取指定(访客)IP所有信息(地址、邮政编码、国家、经纬度等)的方法
Jul 06 PHP
php验证码实现代码(3种)
Sep 07 PHP
如何使用php等比例缩放图片
Oct 12 PHP
PHP使用Nginx实现反向代理
Sep 20 PHP
PHP使用ajax的post方式下载excel文件简单示例
Aug 06 PHP
Yii框架的路由配置方法分析
Sep 09 PHP
Linux系统下安装PHP7.3版本
Jun 26 PHP
PHP封装类似thinkphp连贯操作数据库Db类与简单应用示例
May 08 #PHP
php封装的pdo数据库操作工具类与用法示例
May 08 #PHP
Laravel框架查询构造器简单示例
May 08 #PHP
Laravel Validator 实现两个或多个字段联合索引唯一
May 08 #PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
May 08 #PHP
Laravel框架模型的创建及模型对数据操作示例
May 07 #PHP
Laravel框架路由管理简单示例
May 07 #PHP
You might like
《APMServ 5.1.2》使用图解
2006/10/23 PHP
PHP5+UTF8多文件上传类
2008/10/17 PHP
PHP 遍历XP文件夹下所有文件
2008/11/27 PHP
php下获取Discuz论坛登录用户名、用户组、用户ID等信息的实现代码
2010/12/29 PHP
JSON在PHP中的应用介绍
2012/09/08 PHP
php自动加载机制的深入分析
2013/06/08 PHP
使用Curl进行抓取远程内容时url中文编码问题示例探讨
2013/10/29 PHP
php分页函数示例代码分享
2014/02/24 PHP
PHP中使用SimpleXML检查XML文件结构实例
2015/01/07 PHP
适用于初学者的简易PHP文件上传类
2015/10/29 PHP
你可能不再需要JQUERY
2021/03/09 Javascript
js计算精度问题小结
2013/04/22 Javascript
js显示文本框提示文字的方法
2015/05/07 Javascript
jquery+css实现绚丽的横向二级下拉菜单-附源码下载
2015/08/23 Javascript
Bootstrap前端开发案例一
2016/06/17 Javascript
概述jQuery中的ajax方法
2016/12/16 Javascript
axios封装,使用拦截器统一处理接口,超详细的教程(推荐)
2019/05/02 Javascript
vue-form表单验证是否为空值的实例详解
2019/10/29 Javascript
微信小程序request请求封装,验签代码实例
2019/12/04 Javascript
vue quill editor 使用富文本添加上传音频功能
2020/01/14 Javascript
vue 封装 Adminlte3组件的实现
2020/03/18 Javascript
使用python绘制人人网好友关系图示例
2014/04/01 Python
Python实现子类调用父类的方法
2014/11/10 Python
梯度下降法介绍及利用Python实现的方法示例
2017/07/12 Python
Python3.X 线程中信号量的使用方法示例
2017/07/24 Python
Python中使用支持向量机SVM实践
2017/12/27 Python
python 接口返回的json字符串实例
2018/03/27 Python
对python 生成拼接xml报文的示例详解
2018/12/28 Python
在Python中使用MySQL--PyMySQL的基本使用方法
2019/11/19 Python
python实现计算器简易版
2020/12/17 Python
英国著名的化妆品折扣网站:Allbeauty.com
2016/07/21 全球购物
安全口号大全
2014/06/21 职场文书
大二学生自我检讨书
2014/10/23 职场文书
信息技术研修心得体会
2016/01/08 职场文书
《我的伯父鲁迅先生》教学反思
2016/02/16 职场文书
2019年入党思想汇报
2019/03/25 职场文书