如何在此 Codeigniter 3 应用程序中将与图像上传相关的验证错误存储为快速消息?

How can I store validation errors related to image upload as flash massages in this Codeigniter 3 application?

我正在使用 Codeigniter 3.1.8Bootstrap 开发基本的 博客应用程序 4 .

帖子当然有主图。如果用户没有上传图片,则有一个默认图片

用户可以上传的图像文件有限制:

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

我已经设法显示了对应于上述配置的上传错误消息(出于好奇and/or使用,代码是) .

然而,对于 update() 方法,由于涉及重定向,所有 表单验证消息都存储为 "flash messages".

public function update() {
    // Form data validation rules
    $this->form_validation->set_rules('title', 'Title', 'required',  array('required' => 'The %s field can not be empty'));
    $this->form_validation->set_rules('desc', 'Short description', 'required',  array('required' => 'The %s field can not be empty'));
    $this->form_validation->set_rules('body', 'Body', 'required',  array('required' => 'The %s field can not be empty'));
    $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');

    $id = $this->input->post('id');

    // Update slug (from title)
    if ($this->form_validation->run()) {
        $slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
        $slugcount = $this->Posts_model->slug_count($slug, $id);
        if ($slugcount > 0) {
            $slug = $slug."-".$slugcount;
        }
    } else {
        $slug = $this->input->post('slug');
    }

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

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

    if (isset($_FILES['userfile']['name']) && $_FILES['userfile']['name'] != null) {
        // Use name field in do_upload method
        if (!$this->upload->do_upload('userfile')) {

            $errors = array('error' => $this->upload->display_errors());

            // Dysplay upload validation errors 
            // only if a file is uploaded and there are errors
            if (empty($_FILES['userfile']['name'])) {
                $errors = [];
            }

            if (!empty($errors)) {
                $data['upload_errors'] = $errors;
            }

        } else {
            $data = $this->upload->data();
            $post_image = $data[ 'raw_name'].$data[ 'file_ext'];
        }
    }
    else {
        $post_image = $this->input->post('postimage');
    }

    if ($this->form_validation->run() && empty($errors)) {
        $this->Posts_model->update_post($id, $post_image, $slug);
        $this->session->set_flashdata('post_updated', 'Your post has been updated');
        redirect('/' . $slug);
    } else {
        $this->form_validation->run();
        $this->session->set_flashdata('errors', validation_errors());
        // this line was added later
        // but the bug persists 
        $this->session->set_flashdata('upload_errors', $errors);
        redirect('/dashboard/posts/edit/' . $slug);
    }
}

edit-post.php 视图中 我有:

<input type="hidden" name="postimage" id="postimage" value="<?php echo $post->post_image; ?>">
<label for="postimage">Upload an image</label>
<div class="form-group">
    <input type="file" name="userfile" id="postimage" size="20">
    <?php if ($this->session->flashdata('upload_errors')) { ?>
        <div class="error-messages">
            <?php if(isset($upload_errors)){
                 foreach ($upload_errors as $upload_error) {
                     echo $upload_error;
                 }
            }?>
        </div>
   <?php } ?>
</div>

我无法将图片上传错误消息添加为 "flash messages"。

我该怎么做?

试试这个:

$this->session->set_flashdata('errors', validation_errors());
$this->session->set_flashdata('upload_errors', $errors);

或者您可以从 validation_errors()$errors 创建一个 $errorArray

这应该有效。

public function update() 
{
    // Form data validation rules
    $this->form_validation->set_rules('title', 'Title', 'required',  array('required' => 'The %s field can not be empty'));
    $this->form_validation->set_rules('desc', 'Short description', 'required',  array('required' => 'The %s field can not be empty'));
    $this->form_validation->set_rules('body', 'Body', 'required',  array('required' => 'The %s field can not be empty'));
    $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');

    $id = $this->input->post('id');

    $form_is_valid = $this->form_validation->run()
    $errors = [];

    // Update slug (from title)
    if ($form_is_valid) {
        $slug = url_title(convert_accented_characters($this->input->post('title')), 'dash', TRUE);
        $slugcount = $this->Posts_model->slug_count($slug, $id);
        if ($slugcount > 0) {
            $slug = $slug."-".$slugcount;
        }
    } else {
        $slug = $this->input->post('slug');
        $errors[] = validation_errors();
    }

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

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

    if (isset($_FILES['userfile']['name']) && $_FILES['userfile']['name'] != null) {
        // Use name field in do_upload method
        if (!$this->upload->do_upload('userfile')) {

            $upload_errors = array('error' => $this->upload->display_errors());

            // Dysplay upload validation errors 
            // only if a file is uploaded and there are errors
            if (empty($_FILES['userfile']['name'])) {
                $upload_errors = [];
            }

            if (!empty($upload_errors)) {
                $data['upload_errors'] = $upload_errors;
                $errors[] = $upload_errors;
            }

        } else {
            $data = $this->upload->data();
            $post_image = $data[ 'raw_name'].$data[ 'file_ext'];
        }
    }
    else {
        $post_image = $this->input->post('postimage');
    }

    if (empty($errors)) {
        $this->Posts_model->update_post($id, $post_image, $slug);
        $this->session->set_flashdata('post_updated', 'Your post has been updated');
        redirect('/' . $slug);
    } else {
        $this->session->set_flashdata('errors', $errors);
        redirect('/dashboard/posts/edit/' . $slug);
    }
}

$this->form_vlaidation->run() 只调用一次。 错误都保存在同一个数组中(表单验证和上传)。 Post 仅在 $errors 为空时更新。

您应该考虑如何进一步改进代码。

试试这个。在构造函数中添加这个

$this->session->keep_flashdata('errors');

并在视图中使用后删除会话数据

 $this->session->unset_userdata('errors');

我做同样的事情(上传错误进入 flashdata 元素)。以下是它对我的作用:

(我将跳过上传配置...但对于此示例,它存储在一个名为 $config 的数组中)

在我的控制器中:

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

if (!$this->upload->do_upload('userfile'))
{
   $this->session->set_flashdata('message', "An error ocurred: ".$this->upload->display_errors());
   $this->session->set_flashdata('alert_class', "alert-danger");
}

else
{
   $this->session->set_flashdata('message', "Upload successful");
   $this->session->set_flashdata('alert_class', "alert-success");

}

在我看来(我所有的观点都带有这个代码)

<?php
if (null !== $this->session->flashdata('message'))
{ ?>
    <div class="alert <?php echo $this->session->flashdata('alert_class'); ?> text-center mb-2"><i class="fas fa-exclamation-triangle fa-fw"></i> <?php echo $this->session->flashdata('message'); ?></div>
<?php 
}
?>

这样,如果我不设置名为 message 的 flashdata 元素,视图甚至不会显示显示警报的 DIV。另一方面,如果我确实设置了 message 元素,则会显示一个 col-12 警报,其中包含我定义的消息,并使用我想要的警报 class 设置样式(成功、警告、危险、信息等)

这仅适用于上传验证错误。在您的多部分表单中,您可能还会有常规的验证错误,您应该单独检查这些错误。您可以对 flash 元素执行相同的操作:

$this->session->set_flashdata('message', validation_errors());

我使用相同的元素名称 (message) 因为我会在第一个错误时停止,所以不会在同一显示中出现上传错误和表单验证错误。

在编辑中-post.php 您必须更改:

<?php if ($this->session->flashdata('upload_errors')) { ?>

与:

<?php if ($upload_errors = $this->session->flashdata('upload_errors')) { ?>