【问题标题】:How to display disallowed file type error message in case of upload in Codeigniter 3?在 Codeigniter 3 中上传时如何显示不允许的文件类型错误消息?
【发布时间】:2020-04-22 09:25:20
【问题描述】:

我正在使用 Codeigniter 3.1.8Bootstrap 4 开发基本的 blog application

这些帖子当然有主要图片。如果用户没有上传图片,则有一个默认图片,但如果上传图片,则只允许三种类型:jpg , jpeg 和 png。

想要警告用户以防她/他尝试上传其他文件格式,我在 Posts 控制器中执行了此操作:

// Upload image
$config['upload_path'] = './assets/img/posts';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['max_size'] = '2048';

$this->load->library('upload', $config);

if(!$this->upload->do_upload()){

    $data['uerrors'] = $this->upload->display_errors();

    if ($data['uerrors']) {
        $this->load->view('partials/header', $data);
        $this->load->view('dashboard/create-post');
        $this->load->view('partials/footer');
    } else {
        $post_image = 'default.jpg';
    }

} else {
    $data = array('upload_data' => $this->upload->data());
    $post_image = $_FILES['userfile']['name'];
}

在我看来:

<?php foreach ($uerrors as $uerror): ?>
  <span><?php echo $uerror; ?></span>
<?php endforeach; ?>

然而,我得到一个 Undefined variable: uerrors 错误。

这是整个create()方法:

public function create() {

    // Only logged in users can create posts
    if (!$this->session->userdata('is_logged_in')) {
        redirect('login');
    }

    $data = $this->get_data();
    $data['tagline'] = "Add New Post";

    if ($data['categories']) {
        foreach ($data['categories'] as &$category) {
            $category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
        }
    }

    $this->form_validation->set_rules('title', 'Title', 'required');
    $this->form_validation->set_rules('desc', 'Short description', 'required');
    $this->form_validation->set_rules('body', 'Body', 'required');
    $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');

    if($this->form_validation->run() === FALSE){
        $this->load->view('partials/header', $data);
        $this->load->view('dashboard/create-post');
        $this->load->view('partials/footer');
    } else {
        // Create slug (from title)
        $slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
        $slugcount = $this->Posts_model->slug_count($slug, null);
        if ($slugcount > 0) {
            $slug = $slug."-".$slugcount;
        }

        // Upload image
        $config['upload_path'] = './assets/img/posts';
        $config['allowed_types'] = 'jpg|jpeg|png';
        $config['max_size'] = '2048';

        $this->load->library('upload', $config);

        if(!$this->upload->do_upload()){

            $data['uerrors'] = $this->upload->display_errors();

            if ($data['uerrors']) {
                $this->load->view('partials/header', $data);
                $this->load->view('dashboard/create-post');
                $this->load->view('partials/footer');
            } else {
                $post_image = 'default.jpg';
            }

        } else {
            $data = array('upload_data' => $this->upload->data());
            $post_image = $_FILES['userfile']['name'];
        }

        $this->Posts_model->create_post($post_image, $slug);
        $this->session->set_flashdata('post_created', 'Your post has been created');
        redirect('/');
    }
} 

我的错误在哪里?

【问题讨论】:

    标签: php validation codeigniter-3


    【解决方案1】:

    此错误告诉您变量不存在或未初始化。看这段代码

    $data['uerrors'] = $this->upload->display_errors();
    
    if ($data['uerrors']) {
    

    我认为您可能在某处(未在此代码中显示)有一个未初始化的 $uerrors 变量。请注意,我不相信array 索引'uerrors' 会在上面的块中给您带来麻烦,因为首先您定义它,其次,如果您引用不存在的array 项目,那么您将收到与问题中引用的不同的错误消息。

    【讨论】:

    • 我知道,但我确实将它传递给$data,那么为什么会出现错误?
    • 我发布了整个create() 方法。
    • @RazvanZamfir 在哪一行崩溃?是if ($data['uerrors']) {
    【解决方案2】:

    你的问题有点含糊。无论如何,设置变量$uerrors 的唯一条件是何时执行create() 方法,我相信该方法将在POST 请求中执行。此外,您没有提到这是视图的哪一部分:

    <?php foreach ($uerrors as $uerror): ?>
      <span><?php echo $uerror; ?> </span>
    <?php endforeach; ?>
    

    如果是dashboard/create-post 视图,则尝试将$data 直接传递给该视图,而不是将其传递给partials/header

    注意:我刚刚检查了 codeigniter View/Controller samples,发现使用 isset() 函数调用检查变量是一个好习惯,因此不要直接执行 foreach 循环,而是这样做:

    <? if (isset($uerrors)): ?>
        <? foreach ($uerrors as $uerror): ?>
          <span><?= $uerror; ?></span>
        <? endforeach; ?> 
    <? endif; ?> 
    

    【讨论】:

    • 请查看整个控制器here,也许这可以澄清一些事情。谢谢您的帮助。 :)
    • 此外,我还检查了dashboard/create-post 视图,但没有找到任何foreach 循环以便我可以验证。它是正确的文件还是另一个文件?
    • 我没有将那部分推送到 GitHub,它会引发错误。 :)
    【解决方案3】:

    您的上传代码看起来不错,但您需要更新以下更改。

    1. 将数据传递给'dashboard/create-post' 视图,就像您传递给'partials/header' 视图一样。您的'dashboard/create-post' 视图没有收到任何上传错误消息,因此它显示的是'Undefined variable: uerrors'。所以,你的上传代码应该是这样的 -
    if(!$this->upload->do_upload()){
        $data['uerrors'] = $this->upload->display_errors();
        if ($data['uerrors']) {
            $this->load->view('partials/header', $data);
            $this->load->view('dashboard/create-post', $data);
            $this->load->view('partials/footer');
        } else {
            $post_image = 'default.jpg';
        }
    } else {
        $post_image = $this->upload->data('file_name');
    }
    
    1. 正如CodeIgniter Documentation 所说,'display_errors()' 返回字符串,而不是数组,您不必遍历错误。只需在您的 'dashboard/create-post' 视图中回显即可。

    为了您的方便,请以不同的方法制作您的上传任务,以便您也可以在更新方法中重复使用它。举个例子-

    private function uploadFile(){
        if ($_FILES['userfile']['name'] === '') {
            return array(
                'status' => TRUE,
                'message' => 'No file selected.',
                'file_name' => 'default.jpg'
            );
        }
    
        // Upload image
        $config['upload_path'] = './assets/img/posts';
        $config['allowed_types'] = 'jpg|jpeg|png';
        $config['max_size'] = '2048';
    
        $this->load->library('upload', $config);
    
        if(!$this->upload->do_upload('userfile')){
            return array(
                'status' => FALSE,
                'message' => $this->upload->display_errors('<p class="text-danger ">', '</p>'),
                'file_name' => ''
            );
        }else{
            return array(
                'status' => TRUE,
                'message' => 'File uploaded successfully',
                'file_name' => $this->upload->data('file_name')
            );
        }
    }
    

    那么你的整个 create 方法应该是这样的 -

    public function create() {
        // Only logged in users can create posts
        if (!$this->session->userdata('is_logged_in')) {
            redirect('login');
        }
    
        $data = $this->get_data();
        $data['tagline'] = "Add New Post";
    
        if ($data['categories']) {
            foreach ($data['categories'] as &$category) {
                $category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
            }
        }
    
        $this->form_validation->set_rules('title', 'Title', 'required');
        $this->form_validation->set_rules('desc', 'Short description', 'required');
        $this->form_validation->set_rules('body', 'Body', 'required');
        $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
    
        if($this->form_validation->run() === FALSE){
            $this->load->view('partials/header', $data);
            $this->load->view('dashboard/create-post');
            $this->load->view('partials/footer');
        } else {
            $upload = $this->uploadFile();
    
            if($upload['status'] === FALSE){
                $data['upload_error'] = $upload['message'];
    
                $this->load->view('partials/header', $data);
                $this->load->view('dashboard/create-post', $data);
                $this->load->view('partials/footer');
            }else{
                // Create slug (from title)
                $slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
                $slugcount = $this->Posts_model->slug_count($slug, null);
                if ($slugcount > 0) {
                    $slug = $slug."-".$slugcount;
                }
    
                $this->Posts_model->create_post($upload['file_name'], $slug);
                $this->session->set_flashdata('post_created', 'Your post has been created');
                redirect('/');
            }
        }
    }
    

    最后在你的'dashboard/create-post'视图文件中添加这行代码,就在文件输入按钮之后。

    <?php if(isset($upload_error)) echo $upload_error; ?>
    

    我认为一切都应该工作。

    【讨论】:

    • 我需要一种方法来告诉用户她/他试图加载错误的文件类型(例如 PDF),不是 没有上传文件。如果没有上传文件,则有一个默认图像(参见$config['allowed_types'] = 'jpg|jpeg|png';)。
    • CodeIgniter 不提供任何选项来自定义上传错误消息。相反,您可以执行以下操作 - 1. 告诉用户在创建帖子页面中支持上传哪些文件类型。 2. 在您的文件输入中使用accept 属性。它只会在选择文件时显示接受的文件类型。检查W3Schools 以了解属性用法。我已经更新了uploadFile() 方法上的错字。请用更新后的代码替换。
    • 我自己提供了一个答案,它对create() 方法效果很好/最好。但是我在update() 上遇到了困难。请查看 this question。谢谢! :)
    【解决方案4】:

    您需要将 $data['uerrors'] 初始化为 null,因为您在前端使用它

    $data['uerrors'] = '';
    

    或者检查前端的值不为空。

    前端,你可以这样做:

    <?php  if (isset($uerrors) && $uerrors != '') {
                foreach ($uerrors as $uerror) {
                    echo '<span>' . $uerror . '</span>';
                }
            } ?>
    

    您的控制器将是:

     $data = array();
            // Upload image
            $config['upload_path'] = './assets/img/posts';
            $config['allowed_types'] = 'jpg|jpeg|png';
            $config['max_size'] = '2048';
    
            $this->load->library('upload', $config);
    
            /*You need to initialize  $data['uerrors'] as null because you are using it on front end*/
            $data['uerrors'] = '';
            if (!$this->upload->do_upload('FilePath')) {
                $data['uerrors'] = $this->upload->display_errors();
                $this->load->view('partials/header', $data);
                $this->load->view('dashboard/create-post');
                $this->load->view('partials/footer');
            } else {
                if (isset($_POST{'your_file'})) {
                    /*'check your images here that you are receiving from front end'*/
                } else {
                    /*If there is no image, then default image is*/
                    $post_image = 'default.jpg';
                }
                $data = array('upload_data' => $this->upload->data());
                $post_image = $_FILES['userfile']['name'];
            }
    

    您可以在How to upload image in CodeIgniter?上进一步找到有用的帖子

    【讨论】:

    • 这对我有用。检查变量是否为空是解决方案。
    【解决方案5】:

    我在这里捡到了三样东西

    1) 如前所述,没有将 $data 传递给正确的视图

    2) 在视图中期望数组而不是字符串,即错误的数据类型

    3) 最后,函数 do_upload() 需要参数字符串 $field。缺少这就是为什么您只有 no upload selected 错误。如果设置了这个参数,codeigniter 真的会抛出错误的文件类型错误。我这样做是为了测试

    在我看来

    <form action="http://localhost:8000/welcome/create" method="post" enctype="multipart/form-data">
              <input type="file" name="lname" ><br>
              <input type="submit" value="Submit">
            </form>
    

    然后在我的控制器中

    if(!$this->upload->do_upload("lname")){
    

    上传错误的文件类型以测试此错误。您可能需要额外的长度来检测实际上传文件的文件类型。

    【讨论】:

      【解决方案6】:

      通过这样修改create(),我已经成功显示上传错误(如果尝试上传,否则使用默认图片):

      public function create() {
      
          // Only logged in users can create posts
          if (!$this->session->userdata('is_logged_in')) {
              redirect('login');
          }
      
          $data = $this->get_data();
          $data['tagline'] = "Add New Post";
      
          if ($data['categories']) {
              foreach ($data['categories'] as &$category) {
                  $category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
              }
          }
      
          $this->form_validation->set_rules('title', 'Title', 'required');
          $this->form_validation->set_rules('desc', 'Short description', 'required');
          $this->form_validation->set_rules('body', 'Body', 'required');
          $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
      
          if($this->form_validation->run() === FALSE){
              $this->load->view('partials/header', $data);
              $this->load->view('dashboard/create-post');
              $this->load->view('partials/footer');
          } else {
              // Create slug (from title)
              $slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
              $slugcount = $this->Posts_model->slug_count($slug, null);
              if ($slugcount > 0) {
                  $slug = $slug."-".$slugcount;
              }
      
              // Upload image
              $config['upload_path'] = './assets/img/posts';
              $config['allowed_types'] = 'jpg|jpeg|png';
              $config['max_size'] = '2048';
      
              $this->load->library('upload', $config);
      
              if(!$this->upload->do_upload()){
      
                  $errors = array('error' => $this->upload->display_errors());
      
                  // Display upload validation errors 
                  // only if a file is uploaded and there are errors
                  if (empty($_FILES['userfile']['name'])) {
                      $errors = [];
                  }
      
                  if (empty($errors)) {
                      $post_image = 'default.jpg';
                  } else {
                      $data['upload_errors'] = $errors;
                  }
      
              } else {
                  $data = array('upload_data' => $this->upload->data());
                  $post_image = $_FILES['userfile']['name'];
              }
      
              if (empty($errors)) {
                  $this->Posts_model->create_post($post_image, $slug);
                  $this->session->set_flashdata('post_created', 'Your post has been created');
                  redirect('/');
              } else {
                  $this->load->view('partials/header', $data);
                  $this->load->view('dashboard/create-post');
                  $this->load->view('partials/footer');
              }
          }
      }
      

      create-post.php 视图中我有:

      <?php if(isset($upload_errors)){
         foreach ($upload_errors as $upload_error) {
          echo $upload_error;
         }
       }?>
      

      【讨论】:

        猜你喜欢
        • 2019-05-20
        • 2011-06-08
        • 1970-01-01
        • 2013-04-04
        • 1970-01-01
        • 2011-11-21
        • 2019-02-27
        • 1970-01-01
        • 2021-01-01
        相关资源
        最近更新 更多