Codeigniter 3 和 Ion-Auth 应用程序错误:未定义的索引用户文件
Codeigniter 3 and Ion-Auth application bug: undefined index userfile
我正在使用 Codeigniter 3 开发 社交网络 应用程序,Ion-Auth and Bootstrap 4. You can see the Github repo HERE.
我尝试在用户注册时添加头像。
为此,我首先在users
table中添加了一个“头像”栏。然后,在我添加的视图中:
<div class="form-group">
<?php $avatar['class'] = 'form-control';
echo lang('edit_user_avatar_label', 'avatar');?>
<input type="file" class="form-control" name="userfile" id="avatar" size="20">
</div>
在 Auth 控制器 (application/controllers/Auth.php
) 中,我创建了这个上传方法:
public function upload_image() {
$config['upload_path'] = './assets/img/avatars';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = 2048;
$this->load->library('upload', $config);
if (!$this->upload->do_upload('userfile')) {
$error = array('error' => $this->upload->display_errors());
$this->_render_page('auth' . DIRECTORY_SEPARATOR . 'create_user', $error);
} else {
$this->data = array('image_metadata' => $this->upload->data());
$this->_render_page('auth' . DIRECTORY_SEPARATOR . 'create_user', $this->data);
}
}
最后,对于现有的 $additional_data
数组,我从原来的 create_user()
方法中添加了行 'avatar' => $_FILES['userfile']['name']
:
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $_FILES['userfile']['name'],
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
上面的行,当从edit_user($id)
方法添加到$data
数组时,没有错误,但是当添加到$additional_data
数组时,它给出了错误:Undefined index: userfile
.
我的错误在哪里?
更新:
我用 <?php echo form_open_multipart("auth/create_user");?>
替换了 <?php echo form_open("auth/create_user");?>
。
结果: 图像文件名(带扩展名)添加到 users
table avatar
列中。但是有一个问题:实际上传 图像到 ./assets/img/avatars
并没有发生。
更新
在 OP 发表的评论中 a link to the full code。查了一下,问题很明显了。我在我的回答下方的评论中描述了它,并进行了修复。在此处复制该评论:
You load the upload library on line 473, in the upload_image()
method. But you are calling $this->upload->data()
in a different method (line 530, in the create_user()
method), where you have not loaded the upload library. Move the code from upload_image()
into create_user()
. Refactor once you have it working if you want, keep it simple until it is
原答案
看起来您已经完成了 the documentation,您的代码与他们提供的示例非常相似。但是您没有完成关键的最后一步,他们解释了如何访问上传文件的详细信息! :-)
他们通过返回带有上传数据的视图来演示如何做到这一点:
$data = array('upload_data' => $this->upload->data());
$this->load->view('upload_success', $data);
所以上传文件信息可以通过 $this->upload->data()
获得,而不是 PHP 的超全局 $_FILES
。
文档继续描述 the data()
method:
data([$index = NULL])
[...]
This is a helper method that returns an array containing all of the data related to the file you uploaded.
[...]
To return one element from the array:
$this->upload->data('file_name'); // Returns: mypic.jpg
因此对于您的 Ion Auth 代码,这应该有效(假设文件名是您需要存储的全部):
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $this->upload->data('file_name'),
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
终于开始工作了!!
if ($this->form_validation->run() === TRUE)
{
$email = strtolower($this->input->post('email'));
$identity = ($identity_column === 'email') ? $email : $this->input->post('identity');
$password = $this->input->post('password');
//return $this->upload_image();
$config['upload_path'] = './assets/img/avatars';
$config['file_ext_tolower'] = TRUE;
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 100;
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
if (!$this->upload->do_upload('userfile'))
{
$error = array('error' => $this->upload->display_errors());
print_r($error);
$file_name = null;
}
else
{
$file_name = $this->upload->data('file_name');
}
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $file_name,
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
print_r($additional_data);
}
结果数组
Array ( [first_name] => admin [last_name] => admin [avatar] => design.png [company] => admin [phone] => 9999999999 )
问题似乎出在您的表单中。我查看了您的代码,发现 auth/create_user.php
使用 form_open()
方法而不是使用 form_open_multipart()
方法,因为正常形式不会 post 文件,因此在您的控制器中没有得到 userfile
来自 $additional_data
变量的索引。
正如其他答案中清楚解释的那样,这里是为您提供的复制和粘贴答案。
重申已经说过的话。
$this->upload->data('file_name'),
不存在,因为您没有执行创建它所需的步骤,因此您收到非常“明确说明”的错误消息。
所以你需要加入...
$config['upload_path'] = './assets/img/avatars/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 100;
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
$this->upload->do_upload('userfile');
所以你的代码变成了...
if ($this->form_validation->run() === TRUE) {
$email = strtolower($this->input->post('email'));
$identity = ($identity_column === 'email') ? $email : $this->input->post('identity');
$password = $this->input->post('password');
//return $this->upload_image();
$config['upload_path'] = './assets/img/avatars/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 100;
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
$this->upload->do_upload('userfile');
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $this->upload->data('file_name'),
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
}
现在,由于您在 do_upload() 方法中有这个,您可以将文件上传代码放在另一个方法中并从两个方法中调用它,这样您就不会“重复自己”。我会把它留给你解决。
更新:可能的重构
创建一个新方法来初始化文件上传
protected function init_do_upload() {
$config['upload_path'] = './assets/img/avatars';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 100;
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
}
您现有的 do_upload() 变为...
/**
* Upload avatar
*/
public function do_upload() {
$this->init_do_upload();
if ( ! $this->upload->do_upload('userfile')) {
$error = array('error' => $this->upload->display_errors());
$this->load->view('upload_form', $error);
} else {
$this->data = array('upload_data' => $this->upload->data());
$this->_render_page('auth' . DIRECTORY_SEPARATOR . 'create_user', $this->data['upload_data']);
}
}
而create_user()中的代码段变为...
if ($this->form_validation->run() === TRUE) {
$email = strtolower($this->input->post('email'));
$identity = ($identity_column === 'email') ? $email : $this->input->post('identity');
$password = $this->input->post('password');
$this->init_do_upload();
$this->upload->do_upload('userfile');
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $this->upload->data('file_name'),
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
}
我正在使用 Codeigniter 3 开发 社交网络 应用程序,Ion-Auth and Bootstrap 4. You can see the Github repo HERE.
我尝试在用户注册时添加头像。
为此,我首先在users
table中添加了一个“头像”栏。然后,在我添加的视图中:
<div class="form-group">
<?php $avatar['class'] = 'form-control';
echo lang('edit_user_avatar_label', 'avatar');?>
<input type="file" class="form-control" name="userfile" id="avatar" size="20">
</div>
在 Auth 控制器 (application/controllers/Auth.php
) 中,我创建了这个上传方法:
public function upload_image() {
$config['upload_path'] = './assets/img/avatars';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = 2048;
$this->load->library('upload', $config);
if (!$this->upload->do_upload('userfile')) {
$error = array('error' => $this->upload->display_errors());
$this->_render_page('auth' . DIRECTORY_SEPARATOR . 'create_user', $error);
} else {
$this->data = array('image_metadata' => $this->upload->data());
$this->_render_page('auth' . DIRECTORY_SEPARATOR . 'create_user', $this->data);
}
}
最后,对于现有的 $additional_data
数组,我从原来的 create_user()
方法中添加了行 'avatar' => $_FILES['userfile']['name']
:
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $_FILES['userfile']['name'],
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
上面的行,当从edit_user($id)
方法添加到$data
数组时,没有错误,但是当添加到$additional_data
数组时,它给出了错误:Undefined index: userfile
.
我的错误在哪里?
更新:
我用 <?php echo form_open_multipart("auth/create_user");?>
替换了 <?php echo form_open("auth/create_user");?>
。
结果: 图像文件名(带扩展名)添加到 users
table avatar
列中。但是有一个问题:实际上传 图像到 ./assets/img/avatars
并没有发生。
更新
在 OP 发表的评论中 a link to the full code。查了一下,问题很明显了。我在我的回答下方的评论中描述了它,并进行了修复。在此处复制该评论:
You load the upload library on line 473, in the
upload_image()
method. But you are calling$this->upload->data()
in a different method (line 530, in thecreate_user()
method), where you have not loaded the upload library. Move the code fromupload_image()
intocreate_user()
. Refactor once you have it working if you want, keep it simple until it is
原答案
看起来您已经完成了 the documentation,您的代码与他们提供的示例非常相似。但是您没有完成关键的最后一步,他们解释了如何访问上传文件的详细信息! :-)
他们通过返回带有上传数据的视图来演示如何做到这一点:
$data = array('upload_data' => $this->upload->data());
$this->load->view('upload_success', $data);
所以上传文件信息可以通过 $this->upload->data()
获得,而不是 PHP 的超全局 $_FILES
。
文档继续描述 the data()
method:
data([$index = NULL])
[...]
This is a helper method that returns an array containing all of the data related to the file you uploaded.
[...]
To return one element from the array:
$this->upload->data('file_name'); // Returns: mypic.jpg
因此对于您的 Ion Auth 代码,这应该有效(假设文件名是您需要存储的全部):
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $this->upload->data('file_name'),
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
终于开始工作了!!
if ($this->form_validation->run() === TRUE)
{
$email = strtolower($this->input->post('email'));
$identity = ($identity_column === 'email') ? $email : $this->input->post('identity');
$password = $this->input->post('password');
//return $this->upload_image();
$config['upload_path'] = './assets/img/avatars';
$config['file_ext_tolower'] = TRUE;
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 100;
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
if (!$this->upload->do_upload('userfile'))
{
$error = array('error' => $this->upload->display_errors());
print_r($error);
$file_name = null;
}
else
{
$file_name = $this->upload->data('file_name');
}
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $file_name,
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
print_r($additional_data);
}
结果数组
Array ( [first_name] => admin [last_name] => admin [avatar] => design.png [company] => admin [phone] => 9999999999 )
问题似乎出在您的表单中。我查看了您的代码,发现 auth/create_user.php
使用 form_open()
方法而不是使用 form_open_multipart()
方法,因为正常形式不会 post 文件,因此在您的控制器中没有得到 userfile
来自 $additional_data
变量的索引。
正如其他答案中清楚解释的那样,这里是为您提供的复制和粘贴答案。
重申已经说过的话。
$this->upload->data('file_name'),
不存在,因为您没有执行创建它所需的步骤,因此您收到非常“明确说明”的错误消息。
所以你需要加入...
$config['upload_path'] = './assets/img/avatars/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 100;
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
$this->upload->do_upload('userfile');
所以你的代码变成了...
if ($this->form_validation->run() === TRUE) {
$email = strtolower($this->input->post('email'));
$identity = ($identity_column === 'email') ? $email : $this->input->post('identity');
$password = $this->input->post('password');
//return $this->upload_image();
$config['upload_path'] = './assets/img/avatars/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 100;
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
$this->upload->do_upload('userfile');
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $this->upload->data('file_name'),
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
}
现在,由于您在 do_upload() 方法中有这个,您可以将文件上传代码放在另一个方法中并从两个方法中调用它,这样您就不会“重复自己”。我会把它留给你解决。
更新:可能的重构
创建一个新方法来初始化文件上传
protected function init_do_upload() {
$config['upload_path'] = './assets/img/avatars';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 100;
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
}
您现有的 do_upload() 变为...
/**
* Upload avatar
*/
public function do_upload() {
$this->init_do_upload();
if ( ! $this->upload->do_upload('userfile')) {
$error = array('error' => $this->upload->display_errors());
$this->load->view('upload_form', $error);
} else {
$this->data = array('upload_data' => $this->upload->data());
$this->_render_page('auth' . DIRECTORY_SEPARATOR . 'create_user', $this->data['upload_data']);
}
}
而create_user()中的代码段变为...
if ($this->form_validation->run() === TRUE) {
$email = strtolower($this->input->post('email'));
$identity = ($identity_column === 'email') ? $email : $this->input->post('identity');
$password = $this->input->post('password');
$this->init_do_upload();
$this->upload->do_upload('userfile');
$additional_data = [
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'avatar' => $this->upload->data('file_name'),
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
];
}