(转)yii2组件之多图上传插件FileInput的详细使用 [ 2.0 版本 ]
作者 白狼
出处: http://www.manks.top/yii2_multiply_images.html
本文版权归作者,欢迎转载,但未经作者同意必须保留 此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
非常实用网上看到了和大家分享一下,出处和原文链接已附;PS:
我只是一个辛勤的搬运工!!
文件上传也写过几篇文章了,包括最基本的yii2文件上传、异步上传到又拍云以及百度编辑器图片上传的问题,貌似不说点多图上传的就不完美。
今天介绍一款多图上传的插件 FileInput,至于为什么选中了TA作为我们上传的插件,一来这货跟Yii2有一腿,用起来方便;二来嘛,用这个插件不仅添加的时候好操作,修改的时候也可以直接通过异步的方式将图片悄无声息的删掉;最值得一提的是,界面效果融合了bootstrap,清爽简洁美观,看起来舒服。
借助一下场景,方便说明
假设我们有一张商品表,一张商品图片表,商品图片表只对商品id和图片地址进行存储
开始前准备工作
1、下载我们所需要的组件
composer require kartik-v/yii2-widget-fileinput "@dev"
2、准备一张商品表和一张商品图片表,商品图片表包括商品id和图片url即可
同步上传多图片操作
我们这里所谓的同步操作,即在添加商品时选择多张图片,然后跟随表单一同提交。来看看怎么使用的。
use kartik\file\FileInput;
// 非ActiveForm的表单
echo '<label class="control-label">图片</label>';
echo FileInput::widget([
'model' => $model,
'attribute' => 'banner[]',
'options' => ['multiple' => true]
]);
//使用ActiveForm的表单
echo $form->field($model, 'banner[]')->widget(FileInput::classname(), [
'options' => ['multiple' => true],
]);
若是要上传多图,记得选择图片的时候多选哦。
如此一来,图片选择好了直接提交表单就好,后端文件上传的程序需要自行处理,如果你还没有实现,可以参考文件上传的基本操作。需要提醒的是,以本文为例,此处我们给商品添加多图片实际是操作了两张数据表。
商品图的异步修改(包括删除\添加)操作
开篇可以看到,对于商品的banner图,我们是跟随表单一同提交而进行的上传,接着我们说一说这个麻烦事:编辑商品的时候如何展示商品图以及如何对商品图进行更新\新增\删除的操作?
首先,我们在controller中获取商品对应的banner图,在编辑商品页面展现banner图之前,我们对其稍微进行一下处理:
// 假设商品的banner图是 $relationBanners的集合, $id是商品的id
// $relationBanners的数据结构如:
/**
* Array
*(
* [0] => Array
* (
* [id] => 1484314
* [goods_id] => 1173376
* [banner] => ./uploads/20160617/146612713857635322241f2.png
* )
*
*)
*/
$relationBanners = Banner::find()->where(['goods_id' => $id])->asArray()->all();
// @param $p1 Array 需要预览的商品图,是商品图的一个集合
// @param $p2 Array 对应商品图的操作属性,我们这里包括商品图删除的地址和商品图的id
$p1 = $p2 = [];
if ($relationBanners) {
foreach ($relationBanners as $k => $v) {
$p1[$k] = $v['banner'];
$p2[$k] = [
// 要删除商品图的地址
'url' => Url::toRoute('/banner/delete'),
// 商品图对应的商品图id
'key' => $v['id'],
];
}
}
return $this->render('banner', [
// other params
'p1' => $p1,
'p2' => $p2,
// 商品id
'id' => $id,
]);
视图文件View的代码可参考
// 视图文件
use kartik\file\FileInput;
<?php
echo $form->field($model, 'banner[]')->label('banner图')->widget(FileInput::classname(), [
'options' => ['multiple' => true],
'pluginOptions' => [
// 需要预览的文件格式
'previewFileType' => 'image',
// 预览的文件
'initialPreview' => $p1,
// 需要展示的图片设置,比如图片的宽度等
'initialPreviewConfig' => $p2,
// 是否展示预览图
'initialPreviewAsData' => true,
// 异步上传的接口地址设置
'uploadUrl' => Url::toRoute(['/goods/async-banner']),
// 异步上传需要携带的其他参数,比如商品id等
'uploadExtraData' => [
'goods_id' => $id,
],
'uploadAsync' => true,
// 最少上传的文件个数限制
'minFileCount' => 1,
// 最多上传的文件个数限制
'maxFileCount' => 10,
// 是否显示移除按钮,指input上面的移除按钮,非具体图片上的移除按钮
'showRemove' => true,
// 是否显示上传按钮,指input上面的上传按钮,非具体图片上的上传按钮
'showUpload' => true,
//是否显示[选择]按钮,指input上面的[选择]按钮,非具体图片上的上传按钮
'showBrowse' => true,
// 展示图片区域是否可点击选择多文件
'browseOnZoneClick' => true,
// 如果要设置具体图片上的移除、上传和展示按钮,需要设置该选项
'fileActionSettings' => [
// 设置具体图片的查看属性为false,默认为true
'showZoom' => false,
// 设置具体图片的上传属性为true,默认为true
'showUpload' => true,
// 设置具体图片的移除属性为true,默认为true
'showRemove' => true,
],
],
// 一些事件行为
'pluginEvents' => [
// 上传成功后的回调方法,需要的可查看data后再做具体操作,一般不需要设置
"fileuploaded" => "function (event, data, id, index) {
console.log(data);
}",
],
]);
?>
如上所述,我们罗列了一些都是组件 FileInput的基本属性和设置,如有所需,可查看文档看属性的详细说明。
按照如上所配置,我们预览下效果图
如果没有商品图:
有两张关联的商品图:
至此,我们顺利并成功的展示了商品图。
需要说明的是,虽然我们创建商品图的时候是同步进行添加的,但是,为了操作方便且实现方便,对于商品图的修改(包括添加\删除)操作,我们选择异步操作,也就是说我们的表单提交实际上仅仅做了一件事,就是商品信息的更新!
先来看商品图的异步上传操作。
商品图上传的地址以及上传需要的额外参数(如商品id)我们都准备好了,额外的参数配置项是uploadExtraData,具体见上面视图文件中的配置。
public function actionAsyncBanner ()
{
// 商品ID
$id = Yii::$app->request->post('goods_id');
// $p1 $p2是我们处理完图片之后需要返回的信息,其参数意义可参考上面的讲解
$p1 = $p2 = [];
// 如果没有商品图或者商品id非真,返回空
if (empty($_FILES['Banner']['name']) || empty($_FILES['Banner']['name']['banner']) || !$id) {
echo '{}';
return;
}
// 循环多张商品banner图进行上传和上传后的处理
for ($i = 0; $i < count($_FILES['Banner']['name']['banner']); $i++) {
// 上传之后的商品图是可以进行删除操作的,我们为每一个商品成功的商品图指定删除操作的地址
$url = '/banner/delete';
// 调用图片接口上传后返回的图片地址,注意是可访问到的图片地址哦
$imageUrl = '';
// 保存商品banner图信息
$model = new Banner;
$model->goods_id = $id;
$model->banner_url = $imageUrl;
$key = 0;
if ($model->save(false)) {
$key = $model->id;
}
// 这是一些额外的其他信息,如果你需要的话
// $pathinfo = pathinfo($imageUrl);
// $caption = $pathinfo['basename'];
// $size = $_FILES['Banner']['size']['banner_url'][$i];
$p1[$i] = $imageUrl;
$p2[$i] = ['url' => $url, 'key' => $key];
}
// 返回上传成功后的商品图信息
echo json_encode([
'initialPreview' => $p1,
'initialPreviewConfig' => $p2,
'append' => true,
]);
return;
}
到此,多图上传的工作我们也就完美的实现了。
为了实现图片的删除效果,这里可以先上传两张图片。你可以单张上传也可以多张上传。
上传成功后你可以刷新当前页面,因为一开始我们就在controller中实现了图片的预览工作,所以理应会展示我们已经上传的两张图片。
按照我们的配置,现在的预览图应该是这样的。
不说废话,我们看图片删除的程序(/banner/delete)实现
public function actionDelete ()
{
// 前面我们已经为成功上传的banner图指定了key,此处的key也即时banner图的id
if ($id = Yii::$app->request->post('key')) {
$model = $this->findModel($id);
$model->delete();
}
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return ['success' => true];
}
需要提醒的是,我们这里只实现了单个图片的删除操作,批量删除的操作需要的话请自行实现(当是锻炼了)。
到此,yii2中多图上传的组件使用以及程序代码我们都给出了具体的实现。
yangguangqi8
最后登录:2023-02-16
在线时长:8小时41分
- 粉丝14
- 金钱1125
- 威望30
- 积分1505
共 2 条评论
深耕细则,看了你这个和白狼的有什么区别,能细化些吗?看到结尾也没有看到新的内容。说好的惊喜呢。
我想问下为啥我这没显示具体图片上的上传删除按钮!