多文件上传功能是用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');
}