推荐个图片上传的扩展 [ 2.0 版本 ]
再也不想用yii2-uploadify等之类的基于flash的文件上传了,其他我就不说,flash现在呵呵了,目前使用如下扩展:kartik-v/yii2-widget-fileinput
官网其实有demo,但是,有些细节没有说明,研究了下,然后整理成blog,有兴趣可以看看,
原文如下:
网上看到一个基于Yii2.x的文件上传功能插件,基于Html5上传,摒弃了传统的flash上传,功能相当实用,现将其使用总结列出:
先看看插件的预览效果吧:
,
废话不多说,开始从头到尾说明
1.Composer安装该插件
composer require kartik-v/yii2-widget-fileinput "@dev"
2.渲染页面效果
create控制器中的代码如下,正常实例化Model以及上传的插件,我这里使用的是一个图片轮播模块,所以AR模型为Rotatain;
public function actionCreate()
{
$model = new Rotatain();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'upload' => new UploadForm()
]);
}
}
模板中的代码如下,model与upload通过render渲染传参,不多说
<?php
$form = ActiveForm::begin([
'options' => [
'class' => 'form-horizontal',
],
'fieldConfig'=>[
'template'=>"<div class='row'><div class='col-lg-1 text-right text-fixed'>{label}</div><div class='col-lg-9'>{input}</div><div class='col-lg-2 errors'>{error}</div></div>",
]
]);
?>
<?= $form->field($upload , 'imageFile')->widget(\kartik\file\FileInput::className(),[
'options' => [
'accept' => 'images/*',
'module' => 'Rotatain'
],
'pluginOptions' => [
'uploadUrl' => Url::to(['upload']),
'uploadExtraData' => [
'model' => 'rotatain' //这个参数可以省略,额外的POST数据,我这里用来保存图片的属性到数据库中方便管理图片资源rotatain为Rotatain AR模型
]
],
//网上很多地方都没详细说明回调触发事件,其实fileupload为上传成功后触发的,三个参数,主要是第二个,有formData,jqXHR以及response参数,上传成功后返回的ajax数据可以在response获取
'pluginEvents' => [
'fileuploaded' => "function (object,data){
$('.field-rotatain-image').show().find('input').val(data.response.imageUrl);
}",
//错误的冗余机制
'error' => "function (){
alert('图片上传失败');
}"
]
]);?>
3.后台上传方法
有些人不明白,其实上传的数据还是通过$_FILE
参数接收
actionUpload定义的方法
public function actionUpload()
{
$uploadForm = new UploadForm();
if(Yii::$app->request->isPost){
$uploadForm->imageFile = UploadedFile::getInstance($uploadForm, 'imageFile');
if($imageUrl = $uploadForm->upload()){
echo Json::encode([
'imageUrl' => $imageUrl,
'error' => '' //上传的error字段,如果没有错误就返回空字符串,否则返回错误信息,客户端会自动判定该字段来认定是否有错
]);
}else{
echo Json::encode([
'imageUrl' => '',
'error' => '文件上传失败'
]);
}
}
}
UploadForm类方法:
<?php
/**
* Created by PhpStorm.
* User: recminy
* Date: 2016/6/26
* Time: 20:52
* email:rewminy@qq.com
*/
namespace backend\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model
{
//use it to save $_FILE data.
/**
* @var $imageFile UploadedFile[];
*/
public $imageFile;
public function rules()
{
return [
//数据验证这里可自己做
//[['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
public function upload()
{
if($this->validate()){
$path = \Yii::getAlias('@upload') . '/' . date("Ymd");
if(!is_dir($path) || !is_writable($path)){
\yii\helpers\FileHelper::createDirectory($path,0777,true);
}
$filePath = $path . '/' . \Yii::$app->request->post('model','') . '_' .md5(uniqid() . mt_rand(10000,99999999)) . '.' . $this->imageFile->extension;
if( $this->imageFile->saveAs($filePath)){
//这里将上传成功后的图片信息保存到数据库
$imageUrl = $this->parseImageUrl($filePath);
$imageModel = new Images();
$imageModel->url = $imageUrl;
$imageModel->addtime = time();
$imageModel->status = 0;
$imageModel->module = \Yii::$app->request->post('model','');
$imageModel->save(false);
return $imageUrl;
}
}
return false;
}
/**
* 这里在upload中定义了上传目录根目录别名,以及图片域名
* 将/var/www/html/gushanxia/upload/20160626/file.png 转化为 http://statics.gushanxia.com/20160626/file.png
* format:http://domain/path/file.extension
* @param $filePath
* @return string
*/
private function parseImageUrl($filePath)
{
if(strpos($filePath,\Yii::getAlias('@upload')) !== false){
return \Yii::$app->params['assetDomain'] . str_replace(\Yii::getAlias('@upload'),'',$filePath);
}else{
return $filePath;
}
}
}
附加:图片的MySQL表结构语句
CREATE TABLE `yii2_images` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL,
`addtime` int(11) NOT NULL,
`module` char(15) NOT NULL DEFAULT '',
`status` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET UTF8;
PS:说明
官网其实有很多demo,只是说明如何渲染页面,没有说明详细的处理回调以及上传返回数据,关键在于如何上传后返回数据:
echo Json::encode([
'imageUrl' => '',
'error' => '文件上传失败'
]);
error字段的定义,以及事件处理的定义:
'pluginEvents' => [
'fileuploaded' => "function (object,data){
$('.field-rotatain-image').show().find('input').val(data.response.imageUrl);
}",
//错误的冗余机制
'fileuploaderror' => "function (){
alert('图片上传失败');
}"
]
其实回调事件不仅仅有以上2个,具体有以下几种类型:
case 'filebatchuploadcomplete':
case 'filebatchuploadsuccess':
case 'fileuploaded':
case 'fileclear':
case 'filecleared':
case 'filereset':
case 'fileerror':
case 'filefoldererror':
case 'fileuploaderror':
case 'filebatchuploaderror':
case 'filedeleteerror':
case 'filecustomerror':
case 'filesuccessremove':
recminy 福建福州
注册时间:2014-09-05
最后登录:2021-07-16
在线时长:65小时45分
最后登录:2021-07-16
在线时长:65小时45分
- 粉丝18
- 金钱2435
- 威望20
- 积分3285
共 6 条评论
刚开始撸博客,写的烂多多见谅
撸的一手好文章
多谢支持!
@recminy 大神,请问我按照你说的做,但是无法上传,报错说少一个uploadFile控制器
由于同时上传多个文件,上传文件不是一个对象,无法访问,不知道大家都是这么处理的?
这个不行啊,上传返回数据一直不成功,选择框那里的数据不变,我加个新输入框接收数据,但又要上传框选择框里面有数据,我要疯了
只要图片上传上去了,然后保存下url,等到insert时候保存不就可以了?为啥一定要选择框里有数据?还是我对你的理解不对?
.field-rotatain-image 这个返回的类我不知道你用的是哪个节点,我测试了很多都无效
这个多图片上传后台怎么处理?
图片可以上传成功了,但写入不了数据库啊,报错:Exception (Unknown Property) 'yii\base\UnknownPropertyException' with message 'Getting unknown property: frontend\models\UploadForm::name'
pluginEvents 下面配置的事件不执行啊!