多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
示例: tp3.1使用webuploader0.1.5插件多图上传,后台php原生接收 [toc] ## :-: **效果** ![](https://box.kancloud.cn/59e943ccf68a48416f89fa40650e68d9_560x270.png) ![](https://box.kancloud.cn/73a63f6e48a8660dc0da5d6157b23b59_582x281.png) - 对应的效果是: 1、上传图片:选择图片-》开始上传图片(上传成功后)-》会显示图片上传成功 && 可以通过下拉框和文本框,一起提交给后端 2、删除图片:点击删除,删除整个节点 3、修改图片附属信息:就是修改下拉框和文本框中的值 - 亮点在于: 1、前端代码的38行,由于我这是存到3个字段,用户不选,会存个默认值,所以会有对应的关系。这样我取值的时候,就可以用图片的$k,因为图片的$k和$imgType的$type_k下标一样 2、下拉框和文本框是通过 后端上传成功后,动态添加的。可不删图片修改值 ## :-: **前端插件代码** 前端代码,保存在.php文件中 ``` php <body> <tr> <th> 教学资质 <div>上传图片</div> </th> <td> <!-- 如果 是空字符串就隐藏,否则就显示xxx_type对应前台是证书名称,xxx_names对应前台是证书编号--> <span>已上传的图片:</span> <div style="overflow: hidden" imgUrl="<?php echo $data['teacher_aptitude_imgs'];?>" id="is_show_img" > <!-- 查出来的字符串转数组,然后遍历显示--> <!--图片类型(对应前台证书名称)--> <?php $imgType = explode(',',$data['teacher_aptitude_imgs_type']); foreach ($imgType as $type_k => $type_v): ?> <?php endforeach;?> <!--图片名称(对应前台证书编号)--> <?php $imgName = explode(',',$data['teacher_aptitude_imgs_names']); foreach ($imgName as $name_k => $name_v): ?> <?php endforeach;?> <!--图片地址--> <?php $imgArr = explode(',',$data['teacher_aptitude_imgs']); foreach ($imgArr as $k => $v): ?> <div style="border:1px solid #CCCCCC;overflow: hidden;"> <div style="float: left;width: 33.3%;" class="del_img"> <div class="del_node"> <img src="http://<?php echo $v;?>" style="width:100px;height:100px;" > <!--点击删除图片后,要在当前$v中删掉这个图片,并且将这张图片在数据库中删除(更新)--> <a href="javascript:;" class="del_btn" style="color:red;" >删除图片</a> *证件名称 <select name="imgs_types[]"> <option value="请选择" <?php if($imgType[$k]=='请选择'){ echo selected;}?> >请选择</option> <option value="联培证" <?php if($imgType[$k]=='联培证'){ echo selected;}?> >联培证</option> <!--循环出所有类型,并标记出默认--> <option value="教师资格证" <?php if($imgType[$k]=='教师资格证'){ echo selected;}?> >教师资格证</option> </select> *证书编号 <input class="del_imgs_names" type="text" name="imgs_names[]" imgs_names_key="<?php echo $k;?>" value="<?php echo $imgName[$k]?>" /> <!--删除del_node节点的时候,要删调这个节点--> <input type="hidden" name="img_url[]" value="<?php echo $v;?>" /> </div> </div> </div> <?php endforeach?> </div> <br /> <div id="uploader-demo"> <!--用来存放item--> <div style="width:800px;height:200px;margin-left:10px;" id="fileList" class="uploader-list"></div> <div id="filePicker">选择图片</div> <div style="width:78px;margin-top:10px;height: 38px;line-height: 38px;text-align: center;background: #0E774A;border-radius: 2px;"><a href="javascript:;" style="color:#fff;text-decoration: none;" id="start">开始上传图片</a></div> <div>支持jpg、png、jpeg格式,建议图片大小不要超过10M</div> </div> </td> </tr> <script> var $list=$("#fileList"); //这几个初始化全局的百度文档上没说明,好蛋疼 var thumbnailWidth = 100; //缩略图高度和宽度 (单位是像素),当宽高度是0~1的时候,是按照百分比计算,具体可以看api文档 var thumbnailHeight = 100; //初始化Web Uploader var uploader = WebUploader.create({ // 选完文件后,是否自动上传。 auto: false, // swf文件路径 swf: '<?php echo CSS_PATH;?>webuploader-0.1.5/Uploader.swf', server: '/index.php?m=teacher&c=teacher&a=uploadImg', // 文件接收服务端。 //duplicate :true,// 重复上传图片,true为可重复false为不可重复 // 选择文件的按钮,可选。内部根据当前运行是创建,可能是input元素,也可能是flash. pick: {id:'#filePicker'}, //第2个参数是修改按钮上面的文字;如果是单图上传,将第3个参数 置为true // 只允许选择图片文件。 accept: { title: 'Images', extensions: 'jpg,jpeg,png', mimeTypes: 'image/*' }, //fileSingleSizeLimit :'10485760' //单张不能超10M。超过10M没有任何提示,只是图片不会添加到队列,也就是选不上图片 //fileVal:'xg', //默认是file 通过打印$FILES就能看到 //method:'post', //请求方式 //fileSizeLimit:'', //20张之和 如果 超过多少M,就不让上传。单位是字节 //fileNumLimit:20 //每次上传,不能超过20张 }); //【图片预览】当有文件添加进来的时候,监听fileQueued事件,通过uploader.makeThumb来创建图片预览图。 uploader.on( 'fileQueued', function( file ) { // console.log(file); //上一行,匿名函数中的file var $li = $( '<div style="display:inline-block" id="' + file.id + '" class="file-item thumbnail">' + '<img>' + '<div class="info">' + file.name + '</div>' + '<span id="del" style="color:red;">删除图片</span>' + '<br /><span id="tis">等待上传中....</span><progress value="0" max="100"></progress>' + '</div>' ), $img = $li.find('img'); // $list为容器jQuery实例 $list.append( $li ); // 创建缩略图 // 如果为非图片文件,可以不用调用此方法。 // thumbnailWidth x thumbnailHeight 为 100 x 100 uploader.makeThumb( file, function( error, src ) { if ( error ) { $img.replaceWith('<span>不能预览</span>'); return; } $img.attr( 'src', src ); }, thumbnailWidth, thumbnailHeight ); }); //【删除图片】 //这种是动态创建的,直接用click或live不行,获取不到。不要绑定,可以在标签中加自定义的函数onclick="aa()" $list.on('click','#del',function(){ //该事件是由$list中id=del的触发的 var id = $(this).parent().attr('id'); //获取$list上的id属性 $(this).parent().remove(); //删除html中的图片 var quId = uploader.getFile(id); //获取图片在队列中的id uploader.removeFile(quId,true); //删除队列中的图片 }); //【手动上传】往后台发送 队列 中的内容 $("#start").on('click',function(){ uploader.upload(); //对象 调 方法 }); //【进度条】文件上传过程中创建进度条实时显示。 uploader.on( 'uploadProgress', function( file, percentage ) { //第2个参数是当前的上传进度,最大是1,所以要*100 $( '#'+file.id ).find('progress').val(percentage*100); $( '#'+file.id ).find('progress').css("background-color","yellow"); //蓝色+黄色配成一个绿色进度条 }); //【成功】文件上传成功,给item添加成功class, 用样式标记上传成功。 uploader.on( 'uploadSuccess', function(file,data) { //第2个参数是php返回的处理结果 console.log(data); $("#" + file.id).find('#del').remove(); //删掉,删除图片 //这是前端的上传成功,后端的成功和失败都在这里处理 if(data.code == 1){ //上传成功 $( '#'+file.id ).find('#tis').text(data.msg).css('color','green'); //进度条的提示语换成上传成功,并将字的改成绿色的 $( '#'+file.id ).append('<input name="img_url[]" type="hidden" value="' + data.url + '">'); $( '#'+file.id ).append('*证书名称 <select name="imgs_types[]">\n' + '<option value="请选择" selected = "selected">请选择</option>\n' + '<option value="联培证">联培证</option>\n' + '<option value="教师资格证">教师资格证</option>\n' + '</select>'); $( '#'+file.id ).append('*证书编号 <input type="text" name="imgs_names[]" value="请输入图片名称">'); }else{ $( '#'+file.id ).find('#tis').text(data.msg).css('color','red'); //显示上传失败 } }); //【失败】文件上传失败,显示上传出错。 uploader.on( 'uploadError', function( file ) { console.log('前端上传失败'); console.log(file); // var $li = $( '#'+file.id ), // $error = $li.find('div.error'); // // // 避免重复创建 // if ( !$error.length ) { // $error = $('<div class="error"></div>').appendTo( $li ); // } // // $error.text('前端上传失败'); }); // 完成上传完了,成功或者失败,先删除进度条。 uploader.on( 'uploadComplete', function( file ) { $( '#'+file.id ).find('progress').remove(); //删除进度条 }); </script> </body> ``` ## :-: **后端php原生上传代码** ``` php /** * 原生上传图片 */ public function uploadImg(){ $file = $_FILES['file']; //接收上传的图片 if($file['size'] >= 10485760){ //大于10M $this->ajaxRtn(23,'图片大于10M'); exit; }else{ if($file['error'] == 0){ //按照年月日创建目录 $savePath='e:/'.date("Y").'/'.date("m").'/'.date("d"); _mkdir($savePath); //效验文件格式 $fileType = explode('/',$file['type']); if(array_key_exists($fileType[1],['jpg','png'])){ $this->ajaxRtn(403,'图片类型不对'); exit; } $filePath = DIR_MANAGE_PATH.'/'.rand(1111,9999).'.png'; //上传到哪个位置 $uploadRes = move_uploaded_file($file['tmp_name'],$filePath); //【关键在这,上传文件】 if($uploadRes){ //文件上传成功 $obj = new \Think\Model('img'); //入库 $data['img'] = $filePath; $res = $obj->add($data); //echo $obj->getLastSql(); $this->ajaxRtn(1,$filePath); //上传成功返回图片地址,以供显示 if(!$res){ $this->ajaxRtn(2,'上传失败'); } } }else{ $this->ajaxRtn(22,'上传错误'); } } } ``` ``` php /** * 返回状态码 * @param $code 状态码 * @param $message 信息 */ public function ajaxRtn($code,$message){ $msg = ['code'=>$code,'msg'=>$message]; echo json_encode($msg); } ``` ``` php function _mkdir($file_path){ //判断给定文件名是否是一个目录 if(!is_dir($file_path)){ mkdir($file_path,0755,true); } } ```