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循环输出数据库内容的代码
May 24 PHP
php mysql数据库操作分页类
Jun 04 PHP
PHP教程 基本语法
Oct 23 PHP
无法在发生错误时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装最快的解决办法
Aug 01 PHP
php中关于普通表单多文件上传的处理方法
Mar 25 PHP
php遍历文件夹和文件列表示例分享
Mar 11 PHP
PHP图片等比例缩放生成缩略图函数分享
Jun 10 PHP
PHP多线程编程之管道通信实例分析
Mar 07 PHP
基于PHP如何把汉字转化为拼音
Dec 11 PHP
yii2.0数据库迁移教程【多个数据库同时同步数据】
Oct 08 PHP
PHP+RabbitMQ实现消息队列的完整代码
Mar 20 PHP
Thinkphp5.0框架视图view的模板布局用法分析
Oct 12 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
阿拉伯的咖啡与水烟
2021/03/03 咖啡文化
Memcache 在PHP中的使用技巧
2010/02/08 PHP
PHP 查找字符串常用函数介绍
2012/06/07 PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
2014/07/29 PHP
高质量PHP代码的50个实用技巧必备(下)
2016/01/22 PHP
简单实现php上传文件功能
2017/09/21 PHP
php 与 nginx 的处理方式及nginx与php-fpm通信的两种方式
2018/09/28 PHP
php操作redis数据库常见方法实例总结
2020/02/20 PHP
js 变量类型转换常用函数与代码[比较全]
2009/12/01 Javascript
Jquery升级新版本后选择器的语法问题
2010/06/02 Javascript
jquery实现tr元素的上下移动示例代码
2013/12/20 Javascript
不使用jquery实现js打字效果示例分享
2014/01/19 Javascript
JavaScript访问CSS属性的几种方式介绍
2014/07/21 Javascript
深入理解javascript变量声明
2014/11/20 Javascript
VC调用javascript的几种方法(推荐)
2016/08/09 Javascript
vue中用动态组件实现选项卡切换效果
2017/03/25 Javascript
微信小程序 连续旋转动画(this.animation.rotate)详解
2017/04/07 Javascript
vue.js组件之间传递数据的方法
2017/07/10 Javascript
jQuery初级教程之网站品牌列表效果
2017/08/02 jQuery
javascript 作用于作用域链的详解
2017/09/27 Javascript
Javascript中JSON数据分组优化实践及JS操作JSON总结
2017/12/22 Javascript
Vue2.0实现组件之间数据交互和通信操作示例
2019/05/16 Javascript
小程序实现新用户判断并跳转激活的方法
2019/05/20 Javascript
javascript实现视频弹幕效果(两个版本)
2019/11/28 Javascript
Python break语句详解
2014/03/11 Python
Python实现的ini文件操作类分享
2014/11/20 Python
python将秒数转化为时间格式的实例
2018/09/16 Python
关于python中remove的一些坑小结
2021/01/04 Python
Hoover胡佛官网:美国吸尘器和洗地机品牌
2019/01/09 全球购物
苏格兰领先的多渠道鞋店:Begg Shoes
2019/10/22 全球购物
七年级生物教学反思
2014/01/30 职场文书
2014年禁毒工作总结
2014/11/24 职场文书
Python实现天气查询软件
2021/06/07 Python
总结python多进程multiprocessing的相关知识
2021/06/29 Python
Python音乐爬虫完美绕过反爬
2021/08/30 Python
Oracle 触发器trigger使用案例
2022/02/24 Oracle