xiaoniao 发表于 2009-10-8 19:10:31

能用的多文件上传扩展类

/* 转载自:phpall.cn
*phpall技术交流群:75345798
*
*
*/
该类来自ci中国,我稍微改了一下。
完整的我测试好的代码在附件中.大家可以去下载.

我对代码做下简单的注释:
先看view层
<form method="POST" enctype="multipart/form-data" action="<?Php echo site_url()?>/welcome/doit">
<input type="file" name="userfile[]">
<input type="file" name="userfile[]">
<input type="file" name="userfile[]"
<input type="submit" value="ok">
</form>
这里我新建了3个上传文件的表单,input的name要使用userfile[]来表示.这个我就不多少了.
然后提交到welcome控制器中的doit函数里面.
接着我们来看控制器
<?php
class Welcome extends Controller {
       function Welcome()
       {
            parent::Controller();      
            $this->load->helper('url');
            $this->load->library('upload');
       }
       function index()
       {
            $this->load->view('welcome_message');
       }
       function multiuploadview(){
            $this->load->view('multi_file_upload');
       }
       function doit(){
            //print_r($_FILES);exit;
            $this->load->library('upload');
            $userfile_data = $_FILES['userfile'];
            $a= $this->upload->do_upload_ex("userfile",$userfile_data,true,"/uploads/","/uploads/",false);
            print_r($a);exit;
            //$b=$this->upload2($a);
            //print_r($b);
       }

}

我们直接看doit函数, $userfile_data = $_FILES['userfile'] 这句话是得到view中表单的上传文件的一些信息的..然后接着是这个函数
$a= $this->upload->do_upload_ex("userfile",$userfile_data,true,"/uploads/","/uploads/",false)
这个函数有点复杂啊,6个参数.现在我们就要来看扩展文件上传类了.
大家在application/library中会看到多出一个文件MY_Upload.php文件.这个就是多文件上传的扩展类.
代码如下:
<?php
class MY_Upload extends CI_Upload{
       function My_Upload(){
            parent::CI_Upload();
       }
       function do_upload_ex($field = 'userfile',$uploaddata,$Multi_file=false,$upload_path,$upload_path_thumb="/uploads/",$pro_thumb=false)
       {
            $CI =& get_instance();
            $imgname = array();
            $uploaddata1[$field] = $uploaddata;
            $_FILES = $uploaddata1;
            if($Multi_file)
            {
                     foreach ($_FILES[$field] as $key => $value){
                            foreach ($value as $key1 => $value1){
                                 $uploadfile["myfile".$key1][$key] =$value1;
                                 //$aaa[]=$uploadfile["myfile".$key1][$key];
                                 //exit;
                            }
                     }
                     //print_r($uploadfile);
                     //echo count($uploadfile);
                     //exit;
                     //unset($uploadfile["myfile0"],$uploadfile["myfile".count($uploadfile)]);
                     //print_r($uploadfile);exit;
                     $_FILES = $uploadfile;
                     //echo $_FILES;exit;
                     //print_r($_FILES);exit;
            }
            $config['upload_path'] = '.'.$upload_path;
            $config['allowed_types'] = 'gif|jpg|png';
            $config['max_size'] = '100';
            $config['max_width'] = '1024';
            $config['max_heigth'] = '768';
            $config['encrypt_name']='TRUE';
            $this->initialize($config);
            foreach($_FILES as $key => $value){
                     if( ! empty($key['name'])){
                            if(!$this->do_upload($key)){            
                                 $error = $this->display_errors();
                                 if($error=="<p>You did not select a file to upload.</p>"){
                                          return $imgname;
                                          }
                                 echo "<script language='JavaScript'>alert('???????????????');history.back();</script>";
                                 exit;
                            }else{
                                 $data['upload_data'] = $this->data();
                                 //print_r($data);exit;
                                 $imgname[] = $data['upload_data']['file_name'];
                                 if($pro_thumb){                        //????????
                                          $CI->load->library('image_lib');
                                          $config['image_library'] = 'gd2';
                                          $config['source_image'] = '.'.$upload_path.$imgname;
                                          $config['new_image'] = '.'.$upload_path_thumb.$imgname;
                                          $config['thumb_marker'] = '';
                                          $config['create_thumb'] = TRUE;
                                          $config['maintain_ratio'] = TRUE;
                                          $config['width'] = 125;
                                          $CI->image_lib->initialize($config);
                                          $CI->image_lib->resize();             //????????
                                 }
                            }
                     }
            }
            return $imgname;
       }
}
?>
我们直接看到do_upload_ex这个函数里面来,
它后面跟着了6个参数,好像一下子看晕了.其中第一个参数是来自view层中input的表单的name值,第二个参数用$_file(userfile)即取得上传文件的一些信息.第三个参数是个bool值就是问你是否是多文件上传,它那里默认是false,即默认不是多文件上传.第四个参数大家应该一看就知道了$upload_path就表示上传的文件的路径,路径是相对index.php而言的这里要注意,并且路径中的文件夹必须是真实的文件,所以你得在那个路径下建立相应的文件夹.第五个则是缩微图的路径,第六个即最后一个参数即是问你时候需要生成缩微图.它默认也是不生成缩微图的.
.函数体中的第一个if语句 if($muliti_file)就是表示你的函数参数中设置了多文件上传的参数为true的时候它就会来执行if里面的语句,if里面使用了2个foreach循环,是用来处理这个二维数组$_FILES($field).两个foreach循环以后就执行$_FILES = $uploadfile;即在$_FILES中存放多个文件的信息。假设$multi_file不存在的话,$_FILES就是if($muliti_file)上面那句的$_FILES里存的单个上传文件的信息了。
接着6个config语句对上传文件做一些初始化操作。
然后又来了一个foreach语句。这里的foreach语句的意思是,因为有多个文件来上传,所以需要用foreach循环来来上传。Foreach语句里面的前面几个if语句是用来处理一些简单e出错信息的,
Else语句是上传的核心代码。
$data['upload_data'] = $this->data(); 这句的意思是将上传后的一些数据放到$data['upload_data']里面去。
$imgname[] = $data['upload_data']['file_name'];这一个语句则是将上传后的文件的文件名放到$imgname里面去。等一下我们可以看到。这个变量是扩展类的返回值。
接下来的一个if语句if($pro_thumb)是当设置了缩微图的时候来执行的操作。后面我就不再解释。

看完了多文件扩展类,现在我们又要回到controller里面来了。
function doit(){
            //print_r($_FILES);exit;
            $this->load->library('upload');
            $userfile_data = $_FILES['userfile'];
            $a = $this->upload->do_upload_ex("userfile",$userfile_data,true,"/uploads/","/uploads/",false);
            print_r($a);exit;
            //$b=$this->upload2($a);
            //print_r($b);
       }
$a = $this->upload->do_upload_ex("userfile",$userfile_data,true,"/uploads/","/uploads/",false);这句是执行扩展类里面的核心函数。我们讲它给$a变量。刚才我们介绍了多文件上传核心函数返回的是上传文件的名字,所以执行完这一句,就可以看到uploads文件夹中有你上传的文件了。打印$a,即可以看到上传文件的名字了。能得到文件的名字就可以将文件的路径插入数据库了。
附件中有完整的测试好的源代码。
在我这里是输入这个url来打开视图页面的,然后选择3个图片上传。就可以看到效果。
http://127.0.0.1/ci_zone/ci_multiupload/index.php/welcome/multiuploadview
最后祝大家好运。有什么疑问或者批评,欢迎大家提出来一起讨论。
个人觉得上面的那个扩展类有点乱,自己试着把这个类改写的简单一点。让处理多文件部分的逻辑作为一个函数,让文件的上传做个一个函数,再让生成缩微图写成一个函数。但没有写成功。

saloyo 发表于 2015-9-30 01:10:33

楼主好人啊

longjianghu 发表于 2009-10-8 21:10:03

有什么特殊设置么,附件的程序运行有问题啊。

xiaoniao 发表于 2009-10-9 00:51:33

请提出来 有什么问题

kazaff 发表于 2009-10-9 08:24:22

好东西啊~~支持~{:3_51:}

xiaoniao 发表于 2009-10-9 10:33:41

楼上的能用吗我在本地测试 是可以的   

大家使用起来有什么问题,请提出来啊。然后我再修改。

wind 发表于 2009-10-10 10:59:18

本帖最后由 wind 于 2009-10-10 11:08 编辑

好象是我写的类?
哈哈。
讲解的很详细。谢谢LZ帮忙修改发布。
支持一下!

xiaoniao 发表于 2009-10-10 11:48:27

志伟来支持了哦啊
6# wind

koo0sky 发表于 2009-10-12 12:11:14

谢谢你的讲解!

chenyong_8888 发表于 2010-7-29 00:27:51

程序没有问题,
在调用的时候有了问题,应该是
function doit(){
            $this->load->library('MY_Upload');
            $userfile_data = $_FILES['userfile'];
            $a = $this->MY_Upload->do_upload_ex("userfile",$userfile_data,true,"/uploads/","/uploads/",false);
            print_r($a);exit;
       }

lcb21 发表于 2011-10-18 09:47:14

{:1_1:}正在找上传呢,学习一下。
页: [1] 2
查看完整版本: 能用的多文件上传扩展类