use kartikfileFileInput;// 非ActiveForm的表单echo "<label class="control-label">图片</label>";echo FileInput::widget(["model" => $model,"attribute" => "image[]","options" => ["multiple" => true]]);//使用ActiveForm的表单echo $form->field($model, "image[]")->widget(FileInput::classname(), ["options" => ["multiple" => true],]);上面上传多图,只需要设置multiple=true即可,记得选择图片的时候多选。
// 视图文件use kartikfileFileInput;<?php $form = ActiveForm::begin(["options" => ["enctype"=>"multipart/form-data"],]); ?><?php echo $form->field($model, "banner_url[]")->label("banner图")->widget(FileInput::classname(), ["options" => ["multiple" => true],"pluginOptions" => [// 需要预览的文件格式"previewFileType" => "image",// 预览的文件"initialPreview" => ["图片1", "图片2", "图片3"],// 需要展示的图片设置,比如图片的宽度等"initialPreviewConfig" => ["width" => "120px"],// 是否展示预览图"initialPreviewAsData" => true,// 异步上传的接口地址设置"uploadUrl" => Url::toRoute(["/goods/async-image"]),// 异步上传需要携带的其他参数,比如商品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);}",],]);?><?php ActiveForm::end(); ?>如上所述,基本上都是组件 FileInput的基本属性和设置,我们这里也仅仅罗列了一些常用的属性介绍,如有所需,可查看文档看属性的详细说明。

感觉上效果很是可以,在开始写php代码实现之前,我们先在controller中实现 initialPreview和 initialPreviewConfig的配置
假设上面的视图文件是用户展示商品图片的详情页,当前controller是指渲染视图文件的controller,则需要在controller中获取商品关联的图片,用于展示或者说用于商品图片的删除新增操作。
// 假设商品的图片是 $relationBanners,$id是商品的id// $relationBanners的数据结构如:/*** Array*(* [0] => Array* (* [id] => 1484314* [goods_id] => 1173376* [banner_url] => ./uploads/20160617/146612713857635322241f2.png* )**)*/$relationBanners = Banner::find()->where(["goods_id" => $id])->asArray()->all();// 对商品banner图进行处理$p1 = $p2 = [];if ($relationBanners) {foreach ($relationBanners as $k => $v) {$p1[$k] = $v["banner_url"];$p2[$k] = ["url" => Url::toRoute("/banner/delete"),"key" => $v["id"],];}}$model = new Banner;return $this->render("banner", ["model" => $model,"p1" => $p1,"p2" => $p2,"id" => $id]);你可以看到p1是图片地址的集合,这里用于赋值给initialPreview"pluginOptions" => [// other code"initialPreview" => $p1,"initialPreviewConfig" => $p2,// other code],注意设置initialPreviewAsData为true哦,不然等会创建图片后,预览图不会显示。
public function actionAsyncImage (){// 商品ID$id = Yii::$app->request->post("goods_id");$p1 = $p2 = [];if (empty($_FILES["Banner"]["name"]) || empty($_FILES["Banner"]["name"]["banner_url"]) || !$id) {echo "{}";return;}for ($i = 0; $i < count($_FILES["Banner"]["name"]["banner_url"]); $i++) {$url = "/banner/delete";$imageUrl = ""; //调用图片接口上传后返回图片地址// 图片入库操作,此处不可以批量直接入库,因为后面我们还要把key返回 便于图片的删除$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;}到此,单图和多图上传的工作我们也就完成了。
不说废话,我们看图片删除的程序(/banner/delete)实现
public function actionDelete (){if ($id = Yii::$app->request->post("key")) {$model = $this->findModel($id);$model->delete();}Yii::$app->response->format = yiiwebResponse::FORMAT_JSON;return ["success" => true];}需要提醒的是,key就是我们配置 initialPreviewConfig项时指定的key,你可以参考controller中的key,也可以参考异步上传成功后p2的key.