韦德国际官网1946CI框架完成优化文件上传及多文件上传的教程

本文实例讲述了Codeigniter实现发送带附件的邮件的方法。分享给大家供大家参考。具体分析如下:

正式接触phpcms模块开发后.开发了几个功能模块.其中遇到了需要批量上传图片的问题.于是开始挖掘phpcms里面的swfupload的用法.

本文实例分析了CI框架实现优化文件上传及多文件上传的方法。分享给大家供大家参考,具体如下:

attach() 方法允许你的发邮件时带上附件,下面是演示代码复制代码
代码如下:$this->load->library;$this->email->from(‘w3@w3mentor.com’,
‘W3M’);$this->email->subject(‘Email Test with
attachment’);$this->email->message(‘Testing the email class IN
CODEIGNITER with
attachment.’);$this->email->attach(‘/path/to/attachment1.jpg’);$this->email->send();

在phpcms里面自带的内容类型里面能够直接指定图片组.不过这样的图片组功能并不是我想用的.我需要上传一整个静态的html文件.需要

最近一直在研究Codeigniter框架,开发项目写到文件上传的时候发现大部分程序员使用Codeigniter框架的文件上传类编写上传方法的时候写的都存在这代码冗余(或者说代码重复利用率低、比较消耗资源。)故而我研究出一个稍微优化一点的上传方法。并且在查找资料时发现,Codeigniter框架同时上传多个文件比较困难,所以在优化方法的同时我又研究了一下如何使用Codeigniter框架实现同时上传多个文件。下面就来和大家分享一下,感兴趣的同学可以关注一下,同时欢迎大家指正错误。

希望本文所述对大家基于Codeigniter的php程序设计有所帮助。

能够找到一个方法上传整个文件夹.并且能够保留原来的文件名称.

1、优化文件上传方法

目的总结如下:

Codeigniter手册里面的那种大家常用的方法在这里就不重复描述了,下面直接说如何对方法进行优化以达到降低代码冗余,提高代码重复利用率的目的。

1,不改变系统的文件和目录结构.

a) 首先在 “ application/config ” 新建 ” upload.php ” 配置文件

2,实现多附件上传功能.

在 “ application/config ” 新建 ” upload.php”
配置文件,在里面写入上传的配置参数。

3,能够得到上传后的文件夹名称.

 

在phpcms中自带了附件上传的功能.我想去用swfupload功能,而这个功能被phpcms的附件上传功能集成进去了.那我要做的就是抽出来并加以修改.

 代码如下

第一步,我来研究研究这个是怎么调用的.

<?php

首先,打开firefox浏览器的firebug
打开网络面板.找到phpcm中swfupload呗调出的那个按钮.看看系统是请求的什么连接.复制代码
代码如下:?m=attachment&c=attachments&a=swfupload&args=10,,1&module=&catid=&authkey=b756a93dea2e627293e88fa9d62af709&pc_hash=iXFbo1我们捕捉到一串这样的请求.调用了attachment模块的attachements控制器里面的swfupload方法.

  defined(‘BASEPATH’) ORexit(‘No direct script access allowed’);

我们去找到这个模块中的这个控制器里面的这个方法.

  //上传的参数配置

在phpcms/modoules/attachemet/attachemts.php里面

  $config[‘upload_path’] =’./public/uploads/’;

打开看看,代码如下复制代码
代码如下:public function swfupload(){ $grouplist = getcache; if(isset{
//if里面的内容我们暂时不看.因为这是上传之后的处理.我们要先找到是如何引入swfupload的.
} else { if($this->isadmin==0 &&
!$grouplist[$this->groupid][‘allowattachment’]) showmessage(L;
$args = $_GET[‘args’];//得到参数 $authkey =
$_GET[‘authkey’];//得到密匙 if != $authkey)
showmessage(L(‘attachment_parameter_error’));//验证密匙
extract(getswfinit;//拆分参数 $siteid =
$this->get_siteid();//得到网站id $site_setting =
get_site_setting;//得到网站设置 $file_size_limit =
sizecount($site_setting[‘upload_maxsize’]*1024);//允许上传大小
$att_not_used = param::get_cookie;//得到未处理的文件列表 if || !isset
$tab_status = ‘ ‘;//如果有未处理的设置标签样式为on if) $div_status = ‘
hidden’;//否则隐藏标签 $att =
$this->att_not_used();//获取临时未处理文件列表 include
$this->admin_tpl;//这个地方才是关键.加载了这个模板. }
}前面的我们就先不管了
,那是处理上传的东西.我从else开始看.首先验证了是否允许附件上传

  $config[‘allowed_types’] =’gif|png|jpg’;

然后从$_GET里面得到swfupload的参数args,然后去验证了密匙,密匙通过了去解析args.得到网站的id,得到网站的设置,得到允许上传附件的大小.从cookie里面得到未使用的附件列表.

  $config[‘max_size’] = 100;

设置模板里面的各种显示.最后也是最关键的.它使用了swfupload模板.也就是说我要找到这个模板.看看swfupload是怎么引过来的.

  $config[‘max_width’] =’1024′;

模板在这里:phpcms/modules/attachment/templates/swfupload.tpl.php

  $config[‘max_height’] =’768′;

打开模板文件.模板文件上面引入了一堆文件:复制代码 代码如下:

 

admin_tpl(‘header’, ‘attachment’);?>

注意:upload_path参数所代表的路径文件夹你已经在项目中创建完毕!

首先是引入了头文件.我大概看里一下.里面有jquery什么的.是必要文件.所以一会我们要用的时候也要引入这个头.

b) 在控制器的构造函数中加载文件上传类

之后是swfupload的样式文件和必要的JS.这里调用了一个系统函数initupload,这个函数到底是干嘛的.

 

千万别小觑这行.整个swfupload的配置都在这里了.

 代码如下

我们去找找看这个函数.

<?php

在phpcms/modules/attachment/functions/golable.func.php里面找到了它的踪迹.代码如下,这个函数的主要作用就是配置swfupload这个插件.复制代码 代码如下:/* flash上传初始化 *
初始化swfupload上传中需要的参数 * @param $module 模块名称 * @param
$catid 栏目id * @param $args 传递参数 * @param $userid 用户id *
@param $groupid 用户组id * @param $isadmin 是否为管理员模式 */
function initupload($module, $catid,$args, $userid, $groupid = ‘8’,
$isadmin = ‘0’){ $grouplist = getcache; if($isadmin==0 &&
!$grouplist[$groupid][‘allowattachment’]) return false; extract;
$siteid = param::get_cookie; $site_setting = get_site_setting;
$file_size_limit = $site_setting[‘upload_maxsize’]; $sess_id =
SYS_TIME; $swf_auth_key = md5(pc_base::load_config.$sess_id);
$init = ‘var swfu = ”; $.ready{ swfu = new SWFUpload({
flash_url:”‘.JS_PATH.’swfupload/swfupload.swf?”+Math.random(),
upload_url:”‘.APP_PATH.’index.php?m=attachment&c=attachments&a=swfupload&dosubmit=1″,
file_post_name : “Filedata”,
post_params:{“SWFUPLOADSESSID”:”‘.$sess_id.'”,”module”:”‘.$module.'”,”catid”:”‘.$_GET[‘catid’].'”,”userid”:”‘.$userid.'”,”siteid”:”‘.$siteid.'”,”dosubmit”:”1″,”thumb_width”:”‘.$thumb_width.'”,”thumb_height”:”‘.$thumb_height.'”,”watermark_enable”:”‘.$watermark_enable.'”,”filetype_post”:”‘.$file_types_post.'”,”swf_auth_key”:”‘.$swf_auth_key.'”,”isadmin”:”‘.$isadmin.'”,”groupid”:”‘.$groupid.'”},
file_size_limit:”‘.$file_size_limit.'”,
file_types:”‘.$file_types.'”, file_types_description:”All Files”,
file_upload_limit:”‘.$file_upload_limit.'”, custom_settings :
{progressTarget : “fsUploadProgress”,cancelButtonId : “btnCancel”},

defined(‘BASEPATH’) ORexit(‘No direct script access allowed’);

button_image_url: “”, button_width: 75, button_height: 28,
button_placeholder_id: “buttonPlaceHolder”, button_text_style: “”,
button_text_top_padding: 3, button_text_left_padding: 12,
button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
button_cursor: SWFUpload.CURSOR.HAND,

/**

file_dialog_start_handler : fileDialogStart, file_queued_handler :
fileQueued, file_queue_error_handler:fileQueueError,
file_dialog_complete_handler:fileDialogComplete,
upload_progress_handler:uploadProgress,
upload_error_handler:uploadError,
upload_success_handler:uploadSuccess,
upload_complete_handler:uploadComplete }); })’; return $init;
}回到正题.我们来看模板swfupload.tpl.php

 * 控制器

这个模板使用了一个js来控制

 */

以页签的形式显示.我们可以用firebug去找到带有我们要找到的swfupload按钮的那个页签的id

classBrandextendsAdmin_Controller

那个id是tab_swf_1

{

这个是一个div 代码如下.复制代码
代码如下:

  publicfunction__construct()

,

  {

onclick=”change_params()”>

    parent::__construct();

在这里我们看到有一个span id是buttonPlaceHolder
而在配置文件中有这么一行button_placeholder_id:
“buttonPlaceHolder”,很明显.当页面被加载的时候
id为buttonPlaceHolder的元素会被JS替换成swfupload的上传控件.

    $this->load->model(‘brand_model’);

之后一步我们要在点选完文件之后触发swf的上传方法

    $this->load->library(‘form_validation’);

会在代码中找到如下代码.这里面调用了swfu.startUpload()方法.这个方法定义的地方在swfupload.js里面.我们无需理会.复制代码
代码如下:至此.我们已经找到了swfupload的上传控件使用方法

    //激活分析器以调试程序

怎么在我的程序里面调用这个东东呢

    $this->output->enable_profiler(TRUE);

首先一点 我们需要在这个控件出现的模板里面引入这些必要的文件复制代码 代码如下:

    //配置中上传的相关参数会自动加载

代码如上所示.

    $this->load->library(‘upload’);

然后在我们的模板里面想要放置swfupload的地方写上这样的标签复制代码 代码如下:

  }

这个地方也就是我之前没有关注的if里面的东西.

}

拿出来看看复制代码 代码如下:if(
$_POST[‘swf_auth_key’] !=
md5(pc_base::load_config.$_POST[‘SWFUPLOADSESSID’]) ||
($_POST[‘isadmin’]==0 &&
!$grouplist[$_POST[‘groupid’]][‘allowattachment’])) exit();
pc_base::load_sys_class; $attachment = new
attachment($_POST[‘module’],$_POST[‘catid’],$_POST[‘siteid’]);
$attachment->set_userid; $aids =
$attachment->upload(‘Filedata’,$_POST[‘filetype_post’],”,”,array($_POST[‘thumb_width’],$_POST[‘thumb_height’]),$_POST[‘watermark_enable’]);
if { $filename= != ‘utf-8’) ? iconv(‘gbk’, ‘utf-8’,
$attachment->uploadedfiles[0][‘filename’]) :
$attachment->uploadedfiles[0][‘filename’];
if($attachment->uploadedfiles[0][‘isimage’]) { echo
$aids[0].’,’.$this->upload_url.$attachment->uploadedfiles[0][‘filepath’].’,’.$attachment->uploadedfiles[0][‘isimage’].’,’.$filename;
} else { $fileext = $attachment->uploadedfiles[0][‘fileext’];
if($fileext == ‘zip’ || $fileext == ‘rar’) $fileext = ‘rar’;
elseif($fileext == ‘doc’ || $fileext == ‘docx’) $fileext = ‘doc’;
elseif($fileext == ‘xls’ || $fileext == ‘xlsx’) $fileext = ‘xls’;
elseif($fileext == ‘ppt’ || $fileext == ‘pptx’) $fileext = ‘ppt’; elseif
($fileext == ‘flv’ || $fileext == ‘swf’ || $fileext == ‘rm’ || $fileext
== ‘rmvb’) $fileext = ‘flv’; else $fileext = ‘do’; echo
$aids[0].’,’.$this->upload_url.$attachment->uploadedfiles[0][‘filepath’].’,’.$fileext.’,’.$filename;
} exit; } else { echo ‘0,’.$attachment->error();
exit;这个里面有几行是比较重要的.

 

首先它载入了系统的attachment类.并且用到了里面的方法.

注意:我们在第一步创建的 “ upload.php ”
文件中的上传配置信息会在这里会自动进行加载。

程序对上传成功做了echo操作.返回的东西是
返回了编号,上传后的地址,拓展名,文件名.

c) 编写上传方法执行do_upload()方法进行文件上传

这些东西是给谁用的啊 我们还得回去看配置文件.

 

配置文件里面有一段是上传过程中各个事件将触发的方法.
有开始上传的.有上传成功的,有上传失败的.等等.

 代码如下

我们可以看见有一个方法是file_dialog_complete_handler:fileDialogComplete,

publicfunctioninsert()

其实这些已经升级到swfupload的范畴了.有兴趣可以去研究研究

{

然后我们在phpcms/static/swfupload/handler.js里面找到这个方法.

  //设置验证规则

看见上传成功后echo出来的数据被解析了.

  $this->form_validation->set_rules(‘brand_name’,’名称’,’required’);

解析的方法如下复制代码
代码如下:function att_show{ var serverData = serverData.replace; var
data = serverData.split; var id = data[0]; var src = data[1]; var
ext = data[2]; var filename = data[3]; if return false; } if { var
img = ‘

  if($this->form_validation->run() == false){

韦德国际官网1946 1‘; } else { var img =

    //未通过验证

韦德国际官网1946 2‘; }
$.get(‘index.php?m=attachment&c=attachments&a=swfupload_json&aid=’+id+’&src=);
$.append(‘

    $data[‘message’] = validation_errors();

‘); $.html; $.append;
$.append;}这个方法的目的是在id为fsuuploadprogress的元素里面添加我们上传成功的附件.但是我们还木有找到文件到底去哪里了

    $data[‘wait’] = 3;

关键的地方来了.我们在swfupload方法里面不是有个attachment的系统类的实例么

    $data[‘url’] = site_url(‘admin/brand/add’);

真正上传附件是在这里实现的.我们调用了attachment里面的upload方法来实现了文件的上传.

    $this->load->view(‘message.html’,$data);

这个attachment文件里面的upload方法在系统类里面
也就是phpcms/libs/classes/attachment.class.php里面

  }else{

在这个类里面我们可以找到upload方法里面有这样一行复制代码 代码如下:$this->savepath =
$this->upload_root.$this->upload_dir.date;这个自然就是指定了上传到的目录.文件名是通过getname方法来获取的.

    //通过验证,处理图片上传

到这里我们就理清思路了.

    if($this->upload->do_upload(‘logo’)) {//logo为前端file控件名

系统是这么运行的

      //上传成功,获取文件名

首先在模板里面引用swfupload->上传文件->attachment模块里的swfupload方法处理(使用系统的attachment类里面的upload方法循环上传附件.并返回结果给swfupload方法)->处理结果通过swfupload的方法返回给页面.

      $fileInfo=$this->upload->data();

在上面我们已经实现了在模板里面引入swfupload.但是我们使用的配置文件和上传附件的方法等都是系统原来自带的.并不能实现我想要的目录结构和文件命名方法.怎么办..

      $data[‘logo’] =$fileInfo[‘file_name’];

改.

      //获取表单提交数据

怎么改,首先们要把配置文件改掉.
在自己的模块里面的functions文件夹里面建立自己的函数.我们用自己的函数名称
文件命名为global.func.php这样系统会通过auto_load把我们的函数加载

      $data[‘brand_name’] =$this->input->post(‘brand_name’);

进去我们把系统中attachment模块functions文件夹下面的global.func.php里面的initupload函数全盘拷贝进来.只修改其中的一行复制代码
代码如下:upload_url:”‘.APP_PATH.’index.php?m=你的模块名称&c=你的控制器名称&a=你的方法名称&dosubmit=1″,这样文件就会提交到我们的控制器下面.并且调用我们自己写的方法

      $data[‘url’] =$this->input->post(‘url’);

然后我们去改系统的attachment类
我们在自己的模块下的classes文件夹下面建立一个myattachment.class.php

      $data[‘brand_desc’] =$this->input->post(‘brand_desc’);

写一个我们自己的类.去集成系统的attachment类.我们需要修改几行.首先一点是吧upload方法里面的上传目录改掉.然后是改掉文件名的命名方法.复制代码 代码如下:function upload($field,
$alowexts = ”, $maxsize = 0, $overwrite = 0,$thumb_setting = array(),
$watermark_enable = 1) { if(!isset { $this->error = UPLOAD_ERR_OK;
return false; } if || $alowexts == ”) { $site_setting =
$this->_get_site_setting; $alowexts =
$site_setting[‘upload_allowext’]; } $fn =
$_GET[‘CKEditorFuncNum’] ? $_GET[‘CKEditorFuncNum’] : ‘1’;

      $data[‘sort_order’] =$this->input->post(‘sort_order’);

$this->field = $field; $this->savepath =
$this->upload_root.$this->upload_dir.date;//这里我们需要修改下.也可以不修改.在我们实例化这个类的时候再来指定目录.
$this->alowexts = $alowexts; $this->maxsize = $maxsize;
$this->overwrite = $overwrite; $uploadfiles = array(); $description =
isset($GLOBALS[$field.’_description’]) ?
$GLOBALS[$field.’_description’] : array();
if(is_array($_FILES[$field][‘error’])) { $this->uploads =
count($_FILES[$field][‘error’]);
foreach($_FILES[$field][‘error’] as $key => $error) { if($error
=== UPLOAD_ERR_NO_FILE) continue; if($error !== UPLOAD_ERR_OK) {
$this->error = $error; return false; } $uploadfiles[$key] =
array(‘tmp_name’ => $_FILES[$field][‘tmp_name’][$key],
‘name’ => $_FILES[$field][‘name’][$key], ‘type’ =>
$_FILES[$field][‘type’][$key], ‘size’ =>
$_FILES[$field][‘size’][$key], ‘error’ =>
$_FILES[$field][‘error’][$key],
‘description’=>$description[$key],’fn’=>$fn); } } else {
$this->uploads = 1; if $description = ”; $uploadfiles[0] =
array(‘tmp_name’ => $_FILES[$field][‘tmp_name’], ‘name’ =>
$_FILES[$field][‘name’], ‘type’ => $_FILES[$field][‘type’],
‘size’ => $_FILES[$field][‘size’], ‘error’ =>
$_FILES[$field][‘error’],
‘description’=>$description,’fn’=>$fn); }

      $data[‘is_show’] =$this->input->post(‘is_show’);

if(!dir_create { $this->error = ‘8’; return false; } if(!is_dir {
$this->error = ‘8’; return false; } @chmod($this->savepath, 0777);

      //调用模型完成添加动作

if(!is_writeable { $this->error = ‘9’; return false; }
if(!$this->is_allow_upload { $this->error = ’13’; return false;
} $aids = array(); foreach($uploadfiles as $k=>$file) { $fileext =
fileext; if { $this->error = $file[‘error’]; return false; }
if(!preg_match(“/^$/”, $fileext)) { $this->error = ’10’; return
false; } if($this->maxsize && $file[‘size’] > $this->maxsize)
{ $this->error = ’11’; return false; } if(!$this->isuploadedfile {
$this->error = ’12’; return false; } //$temp_filename =
$this->getname;//名称在这里.我们需要修改下 $temp_filename =
$file[‘tmp_name’].$fileext; //修改成原来的系统文件名称. $savefile =
$this->savepath.$temp_filename; $savefile =
preg_replace(“/(php|phtml|php3|php4|jsp|exe|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)/i”,
“_\1\2”, $savefile); $filepath =
preg_replace(new_addslashes(“|^”.$this->upload_root.”|”), “”,
$savefile); if(!$this->overwrite && file_exists continue;
$upload_func = $this->upload_func;
if(@$upload_func($file[‘tmp_name’], $savefile)) {
$this->uploadeds++; @chmod; @unlink; $file[‘name’] =
iconv(“utf-8″,CHARSET,$file[‘name’]); $uploadedfile =
array(‘filename’=>$file[‘name’], ‘filepath’=>$filepath,
‘filesize’=>$file[‘size’], ‘fileext’=>$fileext,
‘fn’=>$file[‘fn’]); $thumb_enable = is_array &&
($thumb_setting[0] > 0 || $thumb_setting[1] > 0 ) ? 1 : 0;
$image = new image($thumb_enable,$this->siteid); if {
$image->thumb($savefile,”,$thumb_setting[0],$thumb_setting[1]);
} if { $image->watermark; } $aids[] = $this->add; } } return
$aids; }注:这里我们可以再系统的attachment模块下建立MY_attachment.php
但是这样会影响系统的附件上传功能.

      if($this->brand_model->add_brand($data)){

在我们自己的控制器里面.我们这个时候就需要加载自己写的类了.复制代码
代码如下:pc_base::load_app_class;其余的操作可以参照系统的attachment模块下的attachments控制器里面的swfupload方法来修改.

        $data[‘message’] =”添加成功”;

至此.我便完成了我的目的.在不改变系统文件目录的基础上.完成我自己想要的文件上传功能.

        $data[‘wait’] = 3;

        $data[‘url’] = site_url(‘admin/brand/index’);

        $this->load->view(‘message.html’,$data);

      }else{

        $data[‘message’] =”添加失败”;

        $data[‘wait’] = 3;

        $data[‘url’] = site_url(‘admin/brand/add’);

        $this->load->view(‘message.html’,$data);

      }

    }else{

      //上传失败

      $data[‘message’] =$this->upload->display_errors();

      $data[‘wait’] = 3;

      $data[‘url’] = site_url(‘admin/brand/add’);

      $this->load->view(‘message.html’,$data);

    }

  }

}

 

注意:上述代码有部分是我项目中的代码,大家可以忽略直接关注关键的上传代码。当你需要上传不同的文件时,你也可以在方法中进行文件上传配置,使用$this->upload->initialize()方法进行配置。

2、同时上传多文件的两种方法

① 方法一思路:对所上传的多个文件进行循环处理

 

 代码如下

/**

 * Codeigniter框架实现多文件上传

 * @author Zhihua_W

 * 方法一:对上传的文件进行循环处理

 */

publicfunctionmultiple_uploads1()

{

  //载入所需文件上传类库

  $this->load->library(‘upload’);

  //配置上传参数

  $upload_config=array(

    ‘upload_path’=>’./public/uploads/’,

    ‘allowed_types’=>’jpg|png|gif’,

    ‘max_size’=>’500’,

    ‘max_width’=>’1024’,

    ‘max_height’=>’768’,

  );

  $this->upload->initialize($upload_config);

  //循环处理上传文件

  foreach($_FILESas$key=>$value)
{

    if(!empty($key[‘name’])) {

      if($this->upload->do_upload($key)) {

        //上传成功

        print_r($this->upload->data());

      }else{

        //上传失败

        echo$this->upload->display_errors();

      }

    }

  }

}

 

② 方法二思路:直接一下将多个文件全部上传然后在对上传过的数据进行处理

 

 代码如下

/**

 * Codeigniter框架实现多文件上传

 * @author Zhihua_W

 * 方法二:直接一下将多个文件全部上传然后在对上传过的数据进行处理

 */

publicfunctionmultiple_uploads2()

{

  $config[‘upload_path’] =’./public/uploads/’;

  //这里的public是相对于index.php的,也就是入口文件,这个千万不能弄错!

  //否则就会报错:”The upload path does not appear to be valid.”;

  $config[‘allowed_types’] =’gif|jpg|png’;

  //我试着去上传其它类型的文件,这里一定要注意顺序!

  //否则报错:”A problem was encountered while attempting to move the
uploaded file to the final destination.”

  //这个错误一般是上传文件的文件名不能是中文名,这个很郁闷!还未解决,大家可以用其它方法,重新改一下文件名就可以解决了!

  //$config[‘allowed_types’] = ‘zip|gz|png|gif|jpg’;(正确)

  //$config[‘allowed_types’] = ‘png|gif|jpg|zip|gz’;(错误)

  $config[‘max_size’] =’1024′;

  $config[‘max_width’] =’1024′;

  $config[‘max_height’] =’768′;

  $config[‘file_name’] = time();//文件名不使用原始名

  $this->load->library(‘upload’,$config);

  if(!$this->upload->do_upload()) {

    echo$this->upload->display_errors();

  }else{

    $data[‘upload_data’]
=$this->upload->data();//上传文件的一些信息

    $img=$data[‘upload_data’][‘file_name’];//取得文件名

    echo$img.”<br>”;

    foreach($data[‘upload_data’]as$item=>$value) {

      echo$item.”:”.$value.”<br>”;

    }

  }

}

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注