【问题标题】:Why does renaming an image file before upload fail in this Codeigniter 3 application?为什么在此 Codeigniter 3 应用程序中在上传之前重命名图像文件失败?
【发布时间】:2020-09-02 13:11:11
【问题描述】:

我正在使用 Codeigniter 3、Ion-Auth 和 Bootstrap 4 开发一个社交网络应用程序。您可以看到 Github repo HERE .

更新

我现在有:

if ($this->form_validation->run() === TRUE)
    {
        //more code here

        $config['upload_path'] = './assets/img/avatars';
        $config['file_ext_tolower']     = TRUE;
        $config['allowed_types']        = 'gif|jpg|jpeg|png';
        $config['max_size']             = 1024;
        $config['max_width']            = 1024;
        $config['max_height']           = 1024;
        $config['encrypt_name']         = TRUE;
        $this->load->library('upload', $config);

        if (!$this->upload->do_upload('userfile')){
            $error = array('error' => $this->upload->display_errors());
            $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'),
        ];
}

上面的代码在将文件名插入avatar列之前正确地对文件名进行了哈希处理,但上传本身永远不会发生。

原码

我正在使用以下代码上传用户图像(头像):

if ($this->form_validation->run() === TRUE)
    {
        //more code here

        $config['upload_path'] = './assets/img/avatars';
        $config['file_ext_tolower']     = TRUE;
        $config['allowed_types']        = 'gif|jpg|jpeg|png';
        $config['max_size']             = 1024;
        $config['max_width']            = 1024;
        $config['max_height']           = 1024;
        $this->load->library('upload', $config);

        if (!$this->upload->do_upload('userfile')){
            $error = array('error' => $this->upload->display_errors());
            $file_name = null;
        } else {
            // get filename with extension
            $file_name = $_FILES['userfile']['name'];
            // get filename without extension
            $file_name_clean = explode('.', $file_name)[0];
            // get filename extension   
            $file_ext = explode('.', $file_name)[1];
            //Add timestamp to filename and hash it
            $file_name = md5($file_name.date('m-d-Y_H:i:s'));
            // add extension
            $file_name = $file_name_clean . '.' . $file_ext;
        }

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

正如您在 else 块中看到的,我通过添加当前时间戳和散列来更改原始文件名。

问题是图像文件本身在上传之前没有相应地重命名。以原名上传(图片未存储在/assets/img/avatars/中)。

为什么会这样?

【问题讨论】:

  • 发布的代码中发生的情况是:服务器收到带有文件内容的请求。文件内容存储在一个临时文件夹中(PHP 会自动为您执行此操作)。然后执行此代码,在其中运行$this->upload->do_upload('userfile'),它基本上检查文件并将其从临时文件夹移动到配置的upload_path-文件夹。如果文件被成功移动(上传完成),您将在一个新变量中生成一个新文件名,您只需将其放入一个数组中。你为什么希望它改变实际的文件名?
  • 这是因为实际文件在您运行$this->upload->do_upload('userfile') 后立即上传。之后您使用 $file_name 变量所做的只是转换文件名以用于该变量,您实际上并没有重命名文件。要实际重命名文件,我建议您查看 PHP 的 rename() 函数,该函数描述为 HERE
  • 如果您希望它以自定义名称保存文件,您应该在运行->do_upload() 之前生成文件名,然后在配置数组中设置新名称:$config['file_name'] = $your_new_name;Here's the manual 关于您可以为上传配置的内容。
  • @MagnusEriksson 是的,这是有道理的。

标签: php codeigniter codeigniter-3


【解决方案1】:

如果使用上传

$config['encrypt_name']         = TRUE;

不要使用 $_FILES

改变

$file_name = $_FILES['userfile']['name'];

$file_name = $this->upload->data('file_name');

config.php直接添加你的路径

$config['base_url'] = "http://localhost/yourname/";

【讨论】:

  • $this->upload->data('file_name') 会抛出一个错误,否则我会使用它,因为我被反复建议过。
  • 我使用带有 PHP 5.6 的 XAMPP 服务器。
  • 我更喜欢该应用程序与较低版本的 PHP 兼容,因为我认为 PHP 具有向后兼容性但不能向前兼容。
  • 我有一个带有 somedomain.com 的虚拟主机。
  • 当然,但我希望应用程序与域无关,所以我使用:$root = "http://".$_SERVER['HTTP_HOST']; $root .= str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']); $config['base_url'] = $root;
【解决方案2】:

试试这个,

$config['upload_path'] = './assets/img/avatars';
$config['file_ext_tolower']     = TRUE;
$config['allowed_types']        = 'gif|jpg|jpeg|png';
$config['max_size']             = 1024;
$config['max_width']            = 1024;
$config['max_height']           = 1024;
$config['file_name']           = "Your Encrypted Name.ext";//add this to your code and try
$this->load->library('upload', $config);

【讨论】:

    【解决方案3】:

    这是最终版本的外观:

    在 Auth 类的顶部,我添加了 $file_name 变量:

    //upload file
    public $file_name = null;
    

    我创建了一个可重复使用的上传方法:

    public function upload_avatar(){
        $config['upload_path'] = './assets/img/avatars';
        $config['file_ext_tolower']     = TRUE;
        $config['allowed_types']        = 'gif|jpg|jpeg|png';
        $config['max_size']             = 1024;
        $config['max_width']            = 1024;
        $config['max_height']           = 1024;
        $config['encrypt_name']         = TRUE;
        $this->upload->initialize($config); 
    
        if (!$this->upload->do_upload('userfile')){
            $error = array('error' => $this->upload->display_errors());
        } else {
            $this->file_name = $this->upload->data('file_name');
        }
    }
    

    我在create_user()edit_user($id) 方法中使用此方法:

    $this->upload_avatar();
    

    然后我在$additional_data$data 数组中添加头像,这两种方法:

    $additional_data = [
        //more code
        'avatar' =>  $this->file_name,
        //more code
    ];
    

    $data = [
        //more code
        'avatar' =>  $this->file_name,
        //more code
    ]
    

    查看 GitHub 提交 HERE

    非常感谢所有帮助过的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-11
      • 2023-03-10
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-18
      相关资源
      最近更新 更多