CodeIgniter 多文件上传不起作用

CodeIgniter Multiple File Upload not working

我正在尝试在一个文件夹中上传多个文件,但出现错误 "You did not select a file to upload."
遇到 PHP 错误

Severity: Warning

Message: is_uploaded_file() expects parameter 1 to be string, array given

Filename: libraries/Upload.php

Line Number: 412

Backtrace:

File: C:\wamp\www\mshaadi\application\controllers\Email.php Line: 55 Function: do_upload

File: C:\wamp\www\mshaadi\index.php Line: 293 Function: require_once

控制器

$conf['upload_path'] = './images';
    $conf['allowed_types'] = 'doc|docx|pdf|jpg|gif|jpeg|png';
    $conf['max_size'] = '9999000';
    $conf['max_width'] = '1024';
    $conf['max_height'] = '768';
    $conf['overwrite'] = TRUE;
    $this->load->library('upload');
    foreach ($_FILES as $fieldname => $fileObject){
            $this->upload->initialize($conf);
        if (!empty($fileObject['name'])){
            if (!$this->upload->do_upload($fieldname)){
                $error = $this->upload->display_errors();
                print_r($error);
            }else{
                 print_r("done");
            }
        }else {
            print_r("no");
        }
    }

查看

<div class="form-group col-md-12">
        <label for="Attach"><strong>Add Attachment</strong><br></label>
        <input type="file" class="btn btn-default btn-file" name="atta[]" id="Attach" multiple="multiple"> 
</div>

这样试试,

function upload_files()
{       
    $config = array();
    $config['upload_path'] = './Images/';
    $config['allowed_types'] = 'gif|jpg|png';
    $config['max_size']      = '0';
    $config['overwrite']     = FALSE;

    $this->load->library('upload');

    $files = $_FILES;
    for($i=0; $i< count($_FILES['userfile']['name']); $i++)
    {           
        $_FILES['userfile']['name']= $files['userfile']['name'][$i];
        $_FILES['userfile']['type']= $files['userfile']['type'][$i];
        $_FILES['userfile']['tmp_name']= $files['userfile']['tmp_name'][$i];
        $_FILES['userfile']['error']= $files['userfile']['error'][$i];
        $_FILES['userfile']['size']= $files['userfile']['size'][$i];    

        $this->upload->initialize($config);
        $this->upload->do_upload();
    }
}

这是有效的

 function do_upload()
    {       
        $this->load->library('upload');

        $files = $_FILES;
        $cpt = count($_FILES['userfile']['name']);
        for($i=0; $i<$cpt; $i++)
        {           
            $_FILES['userfile']['name']= $files['userfile']['name'][$i];
            $_FILES['userfile']['type']= $files['userfile']['type'][$i];
            $_FILES['userfile']['tmp_name']= $files['userfile']['tmp_name'][$i];
            $_FILES['userfile']['error']= $files['userfile']['error'][$i];
            $_FILES['userfile']['size']= $files['userfile']['size'][$i];    

            $this->upload->initialize($this->set_upload_options());
            $this->upload->do_upload();
        }
    }

    private function set_upload_options()
    {   
        //upload an image options
        $config = array();
        $config['upload_path'] = './Images/';
        $config['allowed_types'] = 'gif|jpg|png';
        $config['max_size']      = '0';
        $config['overwrite']     = FALSE;

        return $config;
    }

我将添加我的答案作为对@SachinMarwa 自己的答案的更完整解释。我提交的代码不是不同的代码,而是添加了他的回答中未提及的一些行和细节。

尽管看起来他的答案在技术上是正确的,也许他上面的答案在他们自己的方式上也是正确的,但它们对我不起作用。我必须研究这个问题以找出真正发生的事情,并且我对这个过程有了足够的了解以了解如何编写我自己的解决方案。

首先,参考 Nana Partykar 的评论,"In your controller, i'm not able to see any is_uploaded_file() function ?" 该评论告诉我们,人们误解了这两个名称相似但不同的文件。我知道,因为有一段时间我认为它们一定指的是同一个文件,即控制器文件(名为 "Uploader.php")。我可以看到几乎所有这些问题都涉及相同的 "How to upload multiple files using Ajax" 教程,包括我自己的版本。我们都使用的代码是完全一样的。

但是,控制器文件是 "Uploader.php"。你在哪里看到 $this->upload->do_upload() 或 $this->upload->do_upload('userfile') 甚至 $this->upload->do_upload('files'),这是指一个名为 "Upload.php" 的 system/library 模块文件。请注意,在调用 do_upload() 函数之前,您必须调用此行:$this->load->library('upload', $config);

Sachin Marwha 给了我们一个遍历 $_FILES['userfile'] 数组的 for 循环。假设您上传了三张图片。每个 $_FILES['userfile'] 元素本身由 5 "properties" 组成:名称、类型、tmp_name、错误、大小。您可以在 PHP 上看到这些 $_FILE 属性。

您一次只想将一个文件传递给 do_upload()。您不想一次将所有三个(甚至 20 个)文件传递给 do_upload。这意味着您必须在调用 do_upload() 之前将 $_FILES['userfile'] 数组分解为单独的文件。为此,我创建了 $_FILES 数组的 $_FILES['f'] 元素。我通过在 system/library/Upload.php 文件中设置断点来解决这个问题,在 do_upload($file = 'userfile') 函数中,看看我在哪里得到臭名昭着的“没有 select 文件上传”,每个人(包括我自己)都在抱怨。您会发现,该函数使用表单发送到控制器的原始 $_FILES 数组。但它实际上只使用表单中输入类型=文件的名称。如果您不告诉它表单输入的名称,它将默认为 $_FILES['userfile']。事实证明,这是我最大的问题,因为如果我使用输入字段的名称,那么该字段会传递一个数组或一组文件,而不仅仅是一个文件。所以我不得不制作一个特殊的 $_FILES['f] 元素,并且只传递 $_FILES['f'].

我是这样做的,相信我,我尝试了这个页面和其他页面上的所有版本,不仅仅是一个 Whosebug,还有其他教程:

    $cpt = count($_FILES['userfile']['name']);
    for($i=0; $i < $cpt; $i++)
    {
        unset($config);
        $config = array();
        $config['upload_path']   = $path;
        $config['allowed_types'] = 'gif|jpg|png';
        $config['max_size'] = '1000';
        $config['overwrite'] = TRUE;
        $config['remove_spaces'] = FALSE;
        $config['file_name'] = $_FILES['userfile']['name'][$i];

        // Create a new 'f' element of the $_FILES object, and assign the name, type, tmp_name, error, and size properties to the corresponding 'userfile' of this iteration of the FOR loop.
        $_FILES['f']['name'] =  $_FILES['userfile']['name'][$i];
        $_FILES['f']['type'] = $_FILES['userfile']['type'][$i];
        $_FILES['f']['tmp_name'] = $_FILES['userfile']['tmp_name'][$i];
        $_FILES['f']['error'] = $_FILES['userfile']['error'][$i];
        $_FILES['f']['size'] = $_FILES['userfile']['size'][$i];

        $this->load->library('upload', $config);
        $this->upload->initialize($config);            
        if (! $this->upload->do_upload('f'))
        {
            $data['errors'] = $this->upload->display_errors();
        }
        else
        {
            $data['errors'] = "SUCCESS";
        }

        unset($config);
        $config = array();
        $config['image_library']    = 'gd2';
        $config['source_image']     = $path . $_FILES['userfile']['name'][$i];
        $config['create_thumb']     = TRUE;
        $config['maintain_ratio']   = TRUE;
        $config['thumb_marker']     = '.thumb';
        $config['width']            = 100;
        $config['height']           = 100;

        $this->load->library('image_lib', $config);
        $this->image_lib->clear();
        $this->image_lib->initialize($config);
        $this->image_lib->resize();
        $types = array('.jpg');
    }        

它在 for i 循环中取消设置 $config 数组,然后重新制作 $config 数组,这是为每个图片文件制作缩略图的部分。

完整的控制器上传功能:

    public function upload_asset_photo()
    {
        $data = array();
        $dateArray = explode("/",$this->input->post('date'));
        $date = $dateArray[2] . "/" . $dateArray[0] . "/" . $dateArray[1]; // year/month/day
        $cid = $this->config->item('cid'); // this is a special company id I use, unnecessary to you guys.
        $padded_as_id = sprintf("%010d", $this->uri->segment(3)); // this makes an "asset id" like "3" into "0000000003"
        $path = 'properties_/' . $padded_as_id . '/' . $date . '/'; // file path
        if (!is_dir($path)) {
            mkdir($path,0755,true); //makes the ile path, if it doesn't exist
        }

        $cpt = count($_FILES['userfile']['name']);
        for($i=0; $i < $cpt; $i++)
        {
            unset($config);
            $config = array();
            $config['upload_path']   = $path;
            $config['allowed_types'] = 'gif|jpg|png';
            $config['max_size'] = '1000';
            $config['overwrite'] = TRUE;
            $config['remove_spaces'] = FALSE;
            $config['file_name'] = $_FILES['userfile']['name'][$i];

            $_FILES['f']['name'] =  $_FILES['userfile']['name'][$i];
            $_FILES['f']['type'] = $_FILES['userfile']['type'][$i];
            $_FILES['f']['tmp_name'] = $_FILES['userfile']['tmp_name'][$i];
            $_FILES['f']['error'] = $_FILES['userfile']['error'][$i];
            $_FILES['f']['size'] = $_FILES['userfile']['size'][$i];

            $this->load->library('upload', $config);
            $this->upload->initialize($config);            
            if (! $this->upload->do_upload('f'))
            {
                $data['errors'] = $this->upload->display_errors();
            }
            else
            {
                $data['errors'] = "SUCCESS";
            }

            unset($config);
            $config = array();
            $config['image_library']    = 'gd2';
            $config['source_image']     = $path . $_FILES['userfile']['name'][$i];
            $config['create_thumb']     = TRUE;
            $config['maintain_ratio']   = TRUE;
            $config['thumb_marker']     = '.thumb';
            $config['width']            = 100;
            $config['height']           = 100;

            $this->load->library('image_lib', $config);
            $this->image_lib->clear();
            $this->image_lib->initialize($config);
            $this->image_lib->resize();
            $types = array('.jpg');
        }        

        header('Content-Type: application/json');
        echo json_encode($data);
    }

这应该有效

public function add()
{

    $config = array();
    $config['upload_path'] = './assets/uploaded_images';
    $config['allowed_types'] = 'gif|jpg|png';
    $config['max_size'] = '10000';

    $this->load->library('upload');
    $image_names = array();
    $files = $_FILES;

    if (isset($_FILES['images'])) {
        for ($i = 0; $i < count($_FILES['images']['name']); $i++) {
            $_FILES['image']['name'] = $files['images']['name'][$i];
            $_FILES['image']['type'] = $files['images']['type'][$i];
            $_FILES['image']['tmp_name'] = $files['images']['tmp_name'][$i];
            $_FILES['image']['error'] = $files['images']['error'][$i];
            $_FILES['image']['size'] = $files['images']['size'][$i];

            $this->upload->initialize($config);
            $image_names[$i] = $_FILES['image']['name'];
            $this->upload->do_upload('image');

        }
        $data1['images'] = implode(',', $image_names);
        $data1['productId'] = $this->input->post('productId');
        $image_id = $this->Image_model->add_image($data1);
        redirect('image/index');

    } else {
        $error = array('error' => $this->upload->display_errors());
        $this->load->model('Product_model');
        $data['all_products'] = $this->Product_model->get_all_products();
        $data['error'] = $error;
        $data['_view'] = 'image/add';
        $this->load->view('layouts/main', $data);}

}