yii2 使用Plupload实现多图上传(带缩放功能) [ 1.0 版本 ]
这是我学习plupload的相关代码,实现了ajax多图同时上传,然后将图片进行缩放,最后显示图片。
1、文章视图中调用Plupload
<?= \common\widgets\Plupload::widget([
    'model'=>$model,
    'attribute'=>'cover_img',
    'url'=>'/file/upload',//处理文件上传控制器
])?>
2、\common\widgets\Plupload 组件
<?php
namespace common\widgets;
use backend\assets\UploadAsset;
use yii;
use yii\helpers\Html;
use yii\base\Exception;
class Plupload extends yii\bootstrap\Widget{
    public $model;
    public $attribute;
    public $name;
	public $url;
    private $_html;
    public function init(){
        parent::init();
		if(!$this->url){
			throw new Exception('url参数不能为空');
		}
        if(!$this->model){
            throw new Exception('model属性不能为空');
        }
        if(!$this->attribute){
            throw new Exception('attribute属性不能为空');
        }
    }
    public function run(){
        $model = $this->model;
        $attribute = $this->attribute;
        $path = $model->$attribute?$model->$attribute:"/images/noimage.gif";//显示文章图片或者默认图片
        $this->_html.='<div class="form-group field-article-author" id="container">';
        $this->_html.=Html::activeLabel($model,$attribute);
        $this->_html.=Html::activeHiddenInput($model,$attribute,['id'=>'hidden_input','value'=>$path]);
        $this->_html .= '<div id="pickfiles" style="height:50px;min-width:50px;max-width: 300px;overflow: hidden;"><img height="50" src="'.$path.'" /></div>';
        $this->_html.='</div>  ';
        UploadAsset::register($this->view);
		$this->view->registerJs(
			'$(function(){
                initCoverImageUploader("pickfiles","container","2mb","'.$this->url.'","'.Yii::$app->request->getCsrfToken().'");
            });'
		);
        return $this->_html;
    }
}
3、backend\assets\UploadAsset
注册相关js
<?php
namespace backend\assets;
use yii\web\AssetBundle;
class UploadAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
    ];
    public $js = [
        'js/upload.js'
    ];
    public $depends = [
        'backend\assets\PluploadAsset',
    ];
}
4、js/upload.js
ajax处理代码
function initCoverImageUploader(buttonId,contatinerId,maxFileSize,url,csrfToken){
    var uploader = new plupload.Uploader({
        runtimes : 'html5,flash,silverlight,html4',
        browse_button :buttonId, // you can pass an id...
        container: contatinerId, // ... or DOM Element itself
        url : url,
        flash_swf_url : '@vendor/moxiecode/plupload/js/Moxie.swf',
        silverlight_xap_url : '@vendor/moxiecode/plupload//js/Moxie.xap',
        filters : {
            max_file_size : maxFileSize,
            mime_types: [
                {title : "Image files", extensions : "jpg,gif,png"},
                {title : "Zip files", extensions : "zip"}
            ]
        },
        multipart_params:{
            '_csrf':csrfToken
        },
        init: {
            FilesAdded: function(up, files) {
                uploader.start();
            },
            UploadProgress: function(up, file) {
                $('#'+contatinerId+' p').text('已上传:'+file.percent+'%');
            },
            FileUploaded:function (up, file, result) {
                result =  $.parseJSON(result.response);
                if(result.code == 0){
                    $('#'+buttonId).html('<img src="'+result.path+'" height="50" />');
                    $('#hidden_input').val(result.path);
                    //console.log(result.message);
                }
            },
            Error: function(up, err) {
                document.getElementById('console').appendChild(document.createTextNode("\nError #" + err.code + ": " + err.message));
            }
        }
    });
    uploader.init();
}
5、backend\assets\PluploadAsset
注册plupload相关资源
<?php
namespace backend\assets;
use yii\web\AssetBundle;
class PluploadAsset extends AssetBundle
{
    public $sourcePath = '@vendor/moxiecode/plupload';
    public $css = [
    ];
    public $js = [
        'js/plupload.full.min.js',
    ];
    public $depends = [
        'yii\web\JqueryAsset',
    ];
}
6、FileController
控制器调用模型处理上传文件,并且返回结果
class FileController extends BaseController
{
    public function actionUpload(){
        Yii::$app->response->format=Response::FORMAT_JSON;
        $model = New ImageUpload();
        $model->fileInputName = 'file';
        if($model->save()){
            return ['code'=>0,'message'=>$model->getMessage(),'path'=>$model->getUrlPath()];
        }else{
            return ['code'=>1,'message'=>$model->getMessage()];
        }
    }
}
7、common\models\ImageUpload
模型中对上传文件做了一定的检测,然后将源文件按照一定的比例进行缩放
<?php
namespace common\models;
use yii\base\Exception;
use yii\helpers\FileHelper;
use yii\web\UploadedFile;
class ImageUpload extends \yii\base\Object
{
    public $fileInputName = 'file';//上传表单 file name
    public $savePath ;//图像保存根位置
    public $allowExt = ['jpg','png','jpeg','gif','bmp'];//允许上传后缀
    public $maxFileSize=1024100000;//最大大小
    public $allowType = ['image/jpeg','image/bmp','image/gif','image/png','image/pjpeg','image/bmp','image/gif','image/x-png','image/pjpeg','image/bmp', 'image/gif' ,'image/x-png','image/pjpeg','image/bmp','image/gif','image/x-png'];
    private $_uploadFile;//上传文件
    private $filePath;//文件路径
    private $urlPath;//访问路径
    private $res=false;//返回状态
    private $message;//返回信息
    public function getMessage(){
        return $this->message;
    }
    public function getUrlPath(){
        return $this->urlPath;
    }
    public function init(){
        if(!$this->fileInputName) throw new Exception('fileInputName属性不能为空');
        if(!$this->savePath) $this->savePath = \Yii::$app->basePath.'/web/uploads/images';
        $this->savePath = rtrim($this->savePath,'/');
        if(!file_exists($this->savePath)){
            if(! FileHelper::createDirectory($this->savePath)){
                $this->message = '没有权限创建'.$this->savePath;
                return false;
            }
        }
        $this->_uploadFile = UploadedFile::getInstanceByName($this->fileInputName);
        if(!$this->_uploadFile){
            $this->message = '没有找到上传文件';
            return false;
        }
        if($this->_uploadFile->error){
            $this->message = '上传失败';
            return false;
        }
        if(!in_array($this->extension,$this->allowExt) || !in_array($this->type,$this->allowType)){
            $this->message = '该文件类型不允许上传';
            return false;
        }
        if($this->_uploadFile->size> $this->maxFileSize){
            $this->message = '文件过大';
            return false;
        }
        $path = date('Y-m',time());
        if(!file_exists($this->savePath.'/'.$path)){
            FileHelper::createDirectory($this->savePath.'/'.$path);
        }
        $name = substr(\Yii::$app->security->generateRandomString(),-4,4);
        $this->filePath = $this->savePath.'/'.$path.'/'.$this->baseName.'--'.$name.'.'.$this->extension;
        $this->urlPath = '/uploads/images/'.$path.'/'.$this->baseName.'--'.$name.'.'.$this->extension;
    }
    public function save(){
        if($this->_uploadFile->saveAs($this->filePath)){
            $this->CreateThumbnail($this->filePath);//缩放图片
            $this->res = true;
        }else{
            $this->res = false;
        }
        if($this->res){
            $this->message = $this->_uploadFile->baseName.'.'.$this->_uploadFile->extension.'上传成功';
        }else{
            $this->message = $this->_uploadFile->baseName.'.'.$this->_uploadFile->extension.'上传失败';
        }
        return $this->res;
    }
    /**
     * 获取文件名字
     * @return null
     */
    public function getBaseName(){
        if($this->_uploadFile){
            return $this->_uploadFile->baseName;
        }else{
            return null;
        }
    }
    /**
     * 返回文件后缀
     * @return null
     */
    public function getExtension(){
        if($this->_uploadFile){
            return $this->_uploadFile->extension;
        }else{
            return null;
        }
    }
    /**
     * 返回文件类型
     * @return mixed
     */
    public function getType(){
        if($this->_uploadFile){
            return $this->_uploadFile->type;
        }
        return null;
    }
    /**
     * 生成保持原图纵横比的缩略图,支持.png .jpg .gif
     * 缩略图类型统一为.png格式
     * $srcFile     原图像文件名称
     * $toFile      缩略图文件名称,为空覆盖原图像文件
     * $toW         缩略图宽
     * $toH         缩略图高
     * @return bool
     */
    public static function CreateThumbnail($srcFile, $toFile="", $toW=100, $toH=100)
    {
        if ($toFile == "") $toFile = $srcFile;
        $data = getimagesize($srcFile);//返回含有4个单元的数组,0-宽,1-高,2-图像类型,3-宽高的文本描述。
        if (!$data) return false;
        //将文件载入到资源变量im中
        switch ($data[2]) //1-GIF,2-JPG,3-PNG
        {
            case 1:
                if(!function_exists("imagecreatefromgif")) return false;
                $im = imagecreatefromgif($srcFile);
                break;
            case 2:
                if(!function_exists("imagecreatefromjpeg")) return false;
                $im = imagecreatefromjpeg($srcFile);
                break;
            case 3:
                if(!function_exists("imagecreatefrompng")) return false;
                $im = imagecreatefrompng($srcFile);
                break;
        }
        //计算缩略图的宽高
        $srcW = imagesx($im);
        $srcH = imagesy($im);
        $toWH = $toW / $toH;
        $srcWH = $srcW / $srcH;
        if ($toWH <= $srcWH) {
            $ftoW = $toW;
            $ftoH = (int)($ftoW * ($srcH / $srcW));
        } else {
            $ftoH = $toH;
            $ftoW = (int)($ftoH * ($srcW / $srcH));
        }
        if (function_exists("imagecreatetruecolor")) {
            $ni = imagecreatetruecolor($ftoW, $ftoH); //新建一个真彩色图像
            if ($ni) {
                //重采样拷贝部分图像并调整大小 可保持较好的清晰度
                imagecopyresampled($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
            } else {
                //拷贝部分图像并调整大小
                $ni = imagecreate($ftoW, $ftoH);
                imagecopyresized($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
            }
        } else {
            $ni = imagecreate($ftoW, $ftoH);
            imagecopyresized($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
        }
        switch ($data[2]) //1-GIF,2-JPG,3-PNG
        {
            case 1:
                imagegif($ni, $toFile);
                break;
            case 2:
                imagejpeg($ni, $toFile);
                break;
            case 3:
                imagepng($ni, $toFile);
                break;
        }
        ImageDestroy($ni);
        ImageDestroy($im);
        return $toFile;
    }
}
specialnot
            注册时间:2015-08-06
最后登录:2019-08-16
在线时长:27小时54分
    最后登录:2019-08-16
在线时长:27小时54分
- 粉丝43
 - 金钱1175
 - 威望200
 - 积分3445
 
热门源码
- 整合完 yii2-rbac+yii2-admin+adminlte 等库的基础开发后台源码
 - 基于 Yii 2 + Bootstrap 3 搭建一套后台管理系统 CMF
 - 适合初学者学习的一款通用的管理后台
 - yii-goaop - 将 goaop 集成到 Yii,在 Yii 中优雅的面向切面编程
 - yii-log-target - 监控系统异常且多渠道发送异常信息通知
 - 店滴云1.3.0
 - 面向对象的一小步:添加 ActiveRecord 的 Scope 功能
 - Yii2 开源商城 FecShop
 - 基于 Yii2 开发的多店铺商城系统,免费开源 + 适合二开
 - leadshop - 基于 Yii2 开发的一款免费开源且支持商业使用的商城管理系统
 
共 9 条评论
cescdcd
挺好 先收藏了
要都看花了
这个代码都不全
@vendor/moxiecode/plupload这个文件呢
直接用composer到github上下载就好了
@specialnot 地址呢?
@墨轩道人 虽说在github网站搜索一下,就能找到,但是我还是给你一个吧。https://github.com/moxiecode/plupload
@specialnot require 里面是那一行是啥额??
@fredgui "moxiecode/plupload": "*",,应该是这一句
效果还不错好像。。。 http://www.sucaihuo.com/jquery/0/3/demo/
怎么在github 上面直接下载 缺少很多文件啊
能发一下 UploadedFile 和 FileHelper 类吗
没有进度条功能吗?