多文件上传功能是用js实现的flash效果,在我们的ecstore系统中,有两处用到了这种方法(1、商品图片上传;2、模板包上传),实现此功能的主要部分就是调用flash文件(uploader.swf)和 数据保存,接下来就是一起学习怎样去完成“多文件上传”的功能(此处主要是以b2c中多图片上传作为示例)。
为了方便多次调用上传的功能,我们可以写一个包含了调用flash的文件(domfile.html),最后通过
<{include file="domfile.html"}>直接引用到你想要完成多文件上传的html页面中。(文件代码展示如下)
domfile.html
<div class="division" style="margin:0;position:relative"> <!--flash按钮展示层--> <div class="clearfix"> <span id="pic-uploader"> <{button app="desktop" class="btn-upload" label=$___b2c="添加商品图片"|t:'b2c' icon="image_new.gif"}> </span> </div> <!--上传的图片展示层--> <div class="pic-area" id="pic-area"> <input type="hidden" name="image_default" value="<{$goods.image_default_id}>" /> <div id='all-pics' style="width:100%"> <div class="gpic-box"> <{include file="gimage.html" app='image'}> </div> </div> </div> <script> //function setPos(){ /*此处是加载文件上传表单<input type="file"> *$$('.std-upload-txt')[0].setStyle('top',$('pic-uploader').getPosition().y+$('main').getScroll().y); */ //} //window.addEvent('domready',function(){ // setPos.periodical(200); //}); //var goodsEditor = null; var goodsEditFrame = (function(){ // setPos(); /** *此处是删除调用的事件+路径 *goodsEditor = new ShopExGoodsEditor('gEditor',{imgtype:'<{$uploader}>',url:'<{$url}>',goods_id:'<{$goods.id}>'}); */ Ex_Loader('uploader',function(){ /** *此处是弹出的浮动窗口中整个页面的最外层“<div id='add' >” *var main =$('add').getParent('.dialog-content-body').setStyle('position','relative'); *console.info($('add').getParent('.dialog-content-body')); */ new Swiff.Uploader( { allowDuplicates: true, verbose: true, //container:main, //flash上传保存路径 url:'index.php?app=image&ctl=admin_manage&act=gimage_swf_remote&sess_id='+sess_id, //flash路径 path: '<{$file_dir}>/uploader.swf', //允许上传的图片(文件)类型(若果想修改为上传多文件的,在这里加载你要上传的文件的后缀) typeFilter: { 'Images (*.jpg, *.jpeg, *.gif, *.png)': '*.jpg; *.jpeg; *.gif; *.png' }, //图片大小的限制 fileSizeMax:<{$IMAGE_MAX_SIZE}>, target:'pic-uploader', onSelect:function(rs){ if(rs) rs.each(function(v){ if(v.size>this.fileSizeMax){ alert(v.name+'<{t}>\n\n文件超出大小<{/t}>'); }; },this); }, onSelectFail:function(rs){ rs.each(function(v){ if(v.validationError=='sizeLimitMax'){ alert(v.name+'<{t}>\n\n文件超出大小<{/t}>'); }; }); }, onSelectSuccess:function(rs){ var PID='up_'; var _this=this; rs.each(function(v,i){ new Element('div',{'class':'gpic-box','id':PID+v.id}).inject($('all-pics')); }); this.start(); }, onFileOpen:function(e){ $('up_'+e.id).setHTML('<em style="font-size:13px;font-family:Georgia;">0%</em>'); }, onFileProgress:function(e){ $('up_'+e.id).getElement('em').set('text',e.progress.percentLoaded+'%'); }, onFileComplete: function(res){ if(res.response.error){ return new MessageBox.error('<{t}>文件<{/t}>'+res.name+'<{t}>上传失败<{/t}>'); } $('up_'+res.id).setHTML(res.response.text); if(!$E('#pic-area .current')&&$E('#pic-area .gpic')){ $E('#pic-area .gpic').onclick(); } } }); }); })(); </script>接下来我们从控制器中来调用此文件。
index.php
<?php
class useremail_ctl_admin_file extends desktop_controller{
function index(){
$this->finder('useremail_mdl_user',
array(
'title'=>'会员详细信息录入',
'actions'=>array(
array(
'label'=>app::get('useremail')->_('添加信息'),
'icon' => 'add.gif',
'href' => 'index.php?app=useremail&ctl=admin_file&act=add',
/**
* 此处是弹出浮动小窗口
*'target'=>'dialog::{title:\''.app::get('useremail')->_('信息录入').'\',width:700,height:400}'
* /
/**此处是在新窗口打开(两种不同的窗口,会有不同的flash调用方法;这里用新窗口)*/
'target'=>'_blank',
),
),
)
);
}
function add(){
/**此处sess_id的使用场景是:在弹出子窗口中调用domfile.html文件时传给siss_id的参数*/
//$this->pagedata['ssid'] = kernel::single('base_session')->sess_id(); //可有可无
//此处必须有,他是flash的具体地址
$this->pagedata['file_dir'] = &app::get('image')->res_url;
//此处必须有,他是图片大小的限制
$this->pagedata['IMAGE_MAX_SIZE'] = 1024*1024*5;
$this->page('upfile.html');
}
}
<!-- 以下是引入flash页面--> 会员照片:<{include file="domfile.html"}>根据以上的步骤,可以先测试一下效果,看看是不是想要的那种感觉。效果图如下:
在页面调用flash页面效果图:
在弹出子窗口调用flash页面效果
ecstore系统上传图片的保存方法都很完善,我们只需要去看看他们的保存方法,不需要我们在重新去写方法。方法路径是:
“app=image&ctl=admin_manage&act=gimage_swf_remote”
以上的方法只是单独的保存图片相关的信息,返回了图片存储id,还没有与商品关联在一起,以下是保存商品时关联图片的方法。在商品保存方法中,对于图片关联表的保存处理方式如下(只是作为参考):
$arr_remove_image = array(); if( $_POST['goods']['images'] ){ $oImage_attach = app::get('image')->model('image_attach'); /* *根据相关商品id和goods类型查询当前商品已经关联的图片(此操作适合修改商品信息),删除原有的信息,从新做插入操作 */ $arr_image_attach = $oImage_attach->getList('*',array('target_id'=>$goods['goods_id'],'target_type'=>'goods')); foreach ((array)$arr_image_attach as $_arr_image_attach){ if (!in_array($_arr_image_attach['image_id'],$_POST['goods']['images'])){ $arr_remove_image[] = $_arr_image_attach['image_id']; } } } if ( !$oGoods->save($goods) ){ //保存商品数据 $this->end(false,app::get('b2c')->_('您所填写的货号重复,请检查!')); }else{ /*图片的处理*/ if( $goods['images'] ){ $oImage = &app::get('image')->model('image'); if ($arr_remove_image){ foreach($arr_remove_image as $_arr_remove_image) $test = $oImage->delete_image($_arr_remove_image,'goods'); } //保存图片信息 foreach($goods['images'] as $k=>$v){ $test = $oImage->rebuild($v['image_id'],array('S','M','L'),true); } } /**商品相关的其他内容处理及存储*/ }到这里,我们多图片上传处理完成,接下去的操作就是显示等其他的一些方式,就要靠自己去完成了。
多文件上传和多图片上传可以说是一样的原理,只需注意以下几个问题
typeFilter: { 'Images (*.jpg, *.psd,*.gif, *.png,*.bmp,*.zip,*.pdf,*.rar,*.xls,*.xlsx,*.doc,*.docx,*.ppt,*.pptx,*.csv,*.txt,)': '*.jpg; *.jpeg; *.gif; *.png; *.bmp; *.zip; *.pdf; *.rar; *.xls; *.xlsx; *.doc; *.docx; *.ppt; *.pptx; *.csv; *.txt; ' },
function store(){ $file = $this->app->model('file'); $file_name = $_FILES['Filedata']['name']; $hou=explode('.',$file_name); //上传文件名 $hou='.'.end($hou); $extname = array( 1 => '.txt', 2 => '.doc', 3 => '.zip', 4 => '.pdf', 5 => '.rar', 6 => '.xls', 7 => '.xlsx', 8 => '.docx', 9 => '.ppt', 10 => '.pptx', 11 => '.csv', 12=> '.gif', 13=> '.jpg', 14=> '.png', 15=> '.bmp', 16 => '.psd', ); if(!@is_dir(ROOT_DIR."/public/tmp/")){ @mkdir(ROOT_DIR."/public/tmp/",0777,true); } $filepath = ROOT_DIR."/public/tmp/"; //存放的临时路径 $upname =md5(time().'|'.$file_name); //存放的文件名 $pathname=$filepath.$upname; // 临时路径名 $uppath=$_FILES['Filedata']['tmp_name']; if($_FILES['Filedata']['error'] == UPLOAD_ERR_NO_FILE) continue; if(!is_uploaded_file($uppath)) return false; if(!move_uploaded_file($uppath,$pathname)){ return false; } $docname=time().'|'.$file_name; if(in_array($hou,$extname)){ $upfile=array( 'file_id'=>md5(rand(0,9999).microtime()), 'file_name'=>$docname, 'path'=>$pathname, 'addtime'=>time(), ); if(!$file->save($upfile)) return false; $file_id = $upfile['file_id']; } $this->pagedata['gimage']['file_id'] = $file_id; $this->pagedata['gimage']['file_name'] = $file_name; $this->display('gimage.html'); }