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.

我尝试在用户注册时添加头像。

为此,我首先在userstable中添加了一个“头像”栏。然后,在我添加的视图中:

<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'),
    ];
}