php 使用codeigniter上传时“没有选择要上传的文件”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7457152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"did not select a file to upload" when uploading using codeigniter
提问by LiveEn
im trying to upload an image but it always give me "You did not select a file to upload."
我正在尝试上传图片,但它总是给我“您没有选择要上传的文件”。
My controller
我的控制器
function add()
{
$thedate=date('Y/n/j h:i:s');
$replace = array(":"," ","/");
$newname=str_ireplace($replace, "-", $thedate);
$config['upload_path'] = './upload/';
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$config['file_name']=$newname;
$config['max_size'] = '100';
$config['max_width'] = '1024';
$config['max_height'] = '768';
$this->load->library('upload', $config);
//$this->upload->initialize($config);
$this->load->library('form_validation');
$this->form_validation->set_rules('title','title','trim|required');
$this->form_validation->set_rules('description','Description','trim|required');
$image1=$this->input->post('image');
if ($this->form_validation->run()==FALSE){
$this->addview();
return false;
}
if (!$this->upload->do_upload($image1)) {
$error = array('error' => $this->upload->display_errors());
$this->load->view('upload_error', $error);
}
else {
$mage=$this->upload->do_upload($image1);
$data =array(
'title'=>$this->input->post('title'),
'descrip'=>$this->input->post('description'),
'image' => $mage['file_name']
);
$this->load->model('member_functions');
$q=$this->member_functions->insert($data);
}}
all the file requirements and the file permissions are set but i still get the that eror. can someone please tell me what am i doing wrong
所有文件要求和文件权限都已设置,但我仍然收到该错误。有人可以告诉我我做错了什么吗
回答by cenanozen
Parameter to $this->upload->do_upload()
function should be the name of the form field. (If you call it without parameters userfile
would be used). It seems in your case it should be 'image'. Instead of:
$this->upload->do_upload()
函数的参数应该是表单字段的名称。(如果你不带参数调用它userfile
会被使用)。在您的情况下,它似乎应该是“图像”。代替:
$image1=$this->input->post('image');
it should be:
它应该是:
$image1='image';
回答by shihabudheen
- View page
- 查看页面
form tag should contain enctype="multipart/form-data"
.
ie,
<form action='' method=''enctype="multipart/form-data>
<input type='file' name='field_name'/>
表单标签应包含enctype="multipart/form-data"
.
IE,
<form action='' method=''enctype="multipart/form-data>
<input type='file' name='field_name'/>
- controller
- 控制器
and in controller upload code should be $this->upload->do_upload("field_name")
and jsut check whether file reaches in server side by making just print like
并且在控制器上传代码应该是$this->upload->do_upload("field_name")
并且jsut检查文件是否通过像打印一样到达服务器端
print_r($_FILES);
if you get null array then make sure that client side code is correct.
如果您得到空数组,请确保客户端代码正确。
回答by etlds
make sure you use
确保你使用
form_open_multipart()
form_open_multipart()
if you are using the form helper.
如果您正在使用表单助手。
回答by DavidHyogo
I totally agree with the advice about making sure the name of the file element in the form is either userfile or, if different, is passed to the do_upload method. However, for future reference it's also worth noting this line:
我完全同意关于确保表单中文件元素的名称是 userfile 的建议,或者如果不同,则传递给 do_upload 方法。但是,为了将来参考,还值得注意的是这一行:
$image1=$this->input->post('image');
comes before
来之前
if (!$this->upload->do_upload($image1)) {
I found the post
method of the input
class does not return anything until after the do_upload
method is called. Also, you've already called it in the if
statement so you don't need to call it again in the else
clause. After calling do_upload
you now have access to form elements with $this->input->post
and information about the uploaded file with $this->upload->data()
我发现post
的方法input
类不返回任何东西,直到之后do_upload
方法被调用。此外,您已经在if
语句中调用了它,因此您不需要在else
子句中再次调用它。调用后,do_upload
您现在可以访问表单元素$this->input->post
以及有关上传文件的信息$this->upload->data()
回答by TARKUS
This is all too familiar a problem.
这是一个再熟悉不过的问题。
I'm going to add my answer as a fuller explanation to another answer I found here. The code I am submitting is not different code, but rather adds some lines and specifics not mentioned in his answer.
我将把我的答案作为更完整的解释添加到我在这里找到的另一个答案中。我提交的代码不是不同的代码,而是添加了他的回答中未提及的一些行和细节。
Even though it looks like his answer is technically correct, and perhaps the answers above his are also correct in their own way, they didn't work for me. I had to study this problem to find out what is really going on, and I learned enough about the process to understand how to write my own solution.
尽管看起来他的答案在技术上是正确的,也许他上面的答案在他们自己的方式中也是正确的,但它们对我不起作用。我必须研究这个问题以找出真正发生了什么,并且我对这个过程有了足够的了解,以了解如何编写自己的解决方案。
First of all, refer to Nana Partykar's comment, "In your controller, i'm not able to see any is_uploaded_file() function ?" That comment tells us that people are misunderstanding the two files which have similar names, but are different. I know, because for a while I thought they must be referring to the same file, the controller file (named "Uploader.php"). I can see almost all of these questions refer to the same "How to upload multiple files using Ajax" tutorial somewhere out there, my own version, included. The code we are all using is exactly the same.
首先,参考 Nana Partykar 的评论,“在你的控制器中,我看不到任何 is_uploaded_file() 函数?” 该评论告诉我们人们误解了两个名称相似但不同的文件。我知道,因为有一段时间我认为它们一定是指同一个文件,即控制器文件(名为“Uploader.php”)。我可以看到几乎所有这些问题都参考了相同的“如何使用 Ajax 上传多个文件”教程,其中包括我自己的版本。我们都使用的代码完全相同。
But, the controller file is "Uploader.php". Where you see $this->upload->do_upload() or $this->upload->do_upload('userfile') or even $this->upload->do_upload('files'), this is referring to a system/library module file named "Upload.php". Notice that before you call the do_upload() function, you have to invoke this line: $this->load->library('upload', $config);
但是,控制器文件是“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 gave us a for loop that loops through the $_FILES['userfile'] array. Let's say you upload three pictures. Each $_FILES['userfile'] element is itself made up of 5 "properties": name, type, tmp_name, error, size. You can see these $_FILE properties on PHP.
Sachin Marwha 为我们提供了一个循环遍历 $_FILES['userfile'] 数组的 for 循环。假设您上传了三张图片。每个 $_FILES['userfile'] 元素本身由 5 个“属性”组成:名称、类型、tmp_name、错误、大小。您可以在PHP上看到这些 $_FILE 属性。
You only want to pass one file at a time to do_upload(). You don't want to pass all three (or even 20) files at a time to do_upload. That means you have to break down the $_FILES['userfile'] array into individual files before you call do_upload(). To do this, I make a $_FILES['f'] element of the $_FILES array. I figured this out by setting breakpoints in the system/library/Upload.php file, in the do_upload($file = 'userfile') function, to see where I was getting the infamous “did not select a file to upload” that everybody (including myself) keeps complaining about. That function, you will find, uses the original $_FILES array your form sends to your controller. But it really only uses the name of the input type=file from your form. If you don't tell it the name of the form input, it will default to $_FILES['userfile']. As it turns out, that was my biggest problem, because if I used the name of my input field, well, that field passes an array or a collection of files, not just a single file. So I had to make a special $_FILES['f] element, and ONLY pass $_FILES['f'].
您只想一次将一个文件传递给 do_upload()。您不想一次将所有三个(甚至 20 个)文件传递给 do_upload。这意味着您必须在调用 do_upload() 之前将 $_FILES['userfile'] 数组分解为单个文件。为此,我创建了 $_FILES 数组的 $_FILES['f'] 元素。我通过在 system/library/Upload.php 文件中设置断点来解决这个问题,在 do_upload($file = 'userfile') 函数中,看看我在哪里得到臭名昭著的“没有选择要上传的文件”,每个人(包括我自己)一直在抱怨。您会发现该函数使用表单发送到控制器的原始 $_FILES 数组。但它实际上只使用表单中输入 type=file 的名称。如果你不告诉它表单输入的名称,它会默认为 $_FILES[' 用户文件']。事实证明,这是我最大的问题,因为如果我使用输入字段的名称,那么该字段会传递一个数组或一组文件,而不仅仅是单个文件。所以我必须制作一个特殊的 $_FILES['f] 元素,并且只传递 $_FILES['f']。
Here's the way I am doing it, and believe me, I tried all of the versions on this page and others, not just one StackOverflow, but other tutorials, as well:
这是我的做法,相信我,我尝试了此页面和其他页面上的所有版本,不仅仅是一个 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');
}
Where it unsets the $config array within the for i loop, and then remakes the $config array, that's the part that makes the thumbnail images for each picture file.
它在 for i 循环中取消设置 $config 数组,然后重新制作 $config 数组,这是为每个图片文件制作缩略图的部分。
The Complete Controller Upload Function:
完整的控制器上传功能:
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);
}