这个问题太熟悉了。
我将把我的答案作为更完整的解释添加到我找到的另一个答案 here。我提交的代码不是不同的代码,而是添加了一些他的答案中没有提到的行和细节。
尽管看起来他的答案在技术上是正确的,也许他上面的答案在他们自己的方式上也是正确的,但它们对我不起作用。我必须研究这个问题以找出真正发生的事情,并且我对这个过程了解得足够多,以了解如何编写自己的解决方案。
首先,参考 Nana Partykar 的评论,“在你的控制器中,我看不到任何 is_uploaded_file() 函数?”该评论告诉我们,人们误解了名称相似但不同的两个文件。我知道,因为有一段时间我认为它们必须引用同一个文件,即控制器文件(名为“Uploader.php”)。我可以看到几乎所有这些问题都引用了相同的“如何使用 Ajax 上传多个文件”教程,包括我自己的版本。我们都使用的代码完全一样。
但是,控制器文件是“Uploader.php”。在你看到 $this->upload->do_upload() 或 $this->upload->do_upload('userfile') 甚至 $this->upload->do_upload('files') 的地方,这是指系统/名为“Upload.php”的库模块文件。请注意,在调用 do_upload() 函数之前,您必须调用此行: $this->load->library('upload', $config);
Sachin Marwha 为我们提供了一个遍历 $_FILES['userfile'] 数组的 for 循环。假设您上传了三张图片。每个 $_FILES['userfile'] 元素本身由 5 个“属性”组成:名称、类型、tmp_name、错误、大小。您可以在PHP 上看到这些 $_FILE 属性。
您一次只想将一个文件传递给 do_upload()。您不想一次将所有三个(甚至 20 个)文件传递给 do_upload。这意味着您必须在调用 do_upload() 之前将 $_FILES['userfile'] 数组分解为单独的文件。为此,我创建了 $_FILES 数组的 $_FILES['f'] 元素。我通过在 system/library/Upload.php 文件中的 do_upload($file = 'userfile') 函数中设置断点来解决这个问题,看看我在哪里得到了臭名昭著的“没有选择要上传的文件” (包括我自己)一直在抱怨。您会发现,该函数使用表单发送到控制器的原始 $_FILES 数组。但它实际上只使用表单中输入 type=file 的名称。如果您不告诉它表单输入的名称,它将默认为 $_FILES['userfile']。事实证明,这是我最大的问题,因为如果我使用输入字段的名称,那么该字段会传递一个数组或文件集合,而不仅仅是单个文件。所以我必须制作一个特殊的 $_FILES['f] 元素,并且只传递 $_FILES['f']。
这就是我的做法,相信我,我尝试了此页面上的所有版本和其他版本,不仅仅是一个 StackOverflow,还包括其他教程:
$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);
}