【问题标题】:Codeigniter 3 blogging application bug: post slug updates even if there are no changes to the post's titleCodeigniter 3 博客应用程序错误:即使帖子标题没有更改,也要发布 slug 更新
【发布时间】:2020-01-16 02:52:08
【问题描述】:

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

对于此应用程序,帖子由 slug 唯一标识并显示给查看者。

我创建了一种机制,通过在 slug 中添加数字,防止重复 slugs 以防出现重复的帖子标题。这个机制包含在 Posts 控制器的 create()update() 方法中。

update() 方法中,这种机制的功能并不完善:即使帖子标题没有更改,帖子 slug 也会更新(my-post-title 变为 my-post-title -1 如果按下“更新”按钮,即使 id 没有重复的帖子标题)。

这是 Posts 控制器中的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($this->input->post('title'), 'dash', TRUE);
        $slugcount = $this->Posts_model->slug_count($slug);
        if ($slugcount > 0) {
            $slug = $slug."-".$slugcount;
        }

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

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

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

这是 Posts 控制器中的 update() 方法:

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($this->input->post('title'), 'dash', TRUE);
        $slugcount = $this->Posts_model->slug_count($slug);
        if ($slugcount > 0) {
            $slug = $slug."-".$slugcount;
        }
    } else {
        $slug = $this->input->post('slug');
    }

    // Upload image
    $config['upload_path'] = './assets/img/posts';
    $config['allowed_types'] = 'jpg|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());

        } 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()) {
        $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());
        redirect('/dashboard/posts/edit/' . $slug);
    }
}

Posts_model 模型中我有:

// Count the slugs in the posts table
public function slug_count($slug){
    $this->db->select('count(*) as slugcount');
    $this->db->from('posts');
    $this->db->where('slug', $slug);
    $query = $this->db->get();
    return $query->row(0)->slugcount;
}

// Update post
public function update_post($id, $post_image, $slug) {
    $data = [
        'title' => $this->input->post('title'),
        'slug' => $slug,
        'description' => $this->input->post('desc'),
        'content' => $this->input->post('body'),
        'post_image' => $post_image,
        'cat_id' => $this->input->post('category'),
        'updated_at' => date('Y-m-d H:i:s')
    ];

    $this->db->where('id', $id);
    return $this->db->update('posts', $data);
}

我应该如何更改上面的代码以修复上述错误?

【问题讨论】:

    标签: php codeigniter codeigniter-3


    【解决方案1】:

    这是因为它也在计算自己,并且在更新时总是大于 1,所以你需要添加另一个 where 语句(并传递 'id' 参数)

    $this->db->where('id !=', $id);
    

    到'slug_count'函数之后

    $this->db->where('slug', $slug);
    

    所以它不会自己计算

    总结一下: 在create()方法改成这样:

    $slugcount = $this-&gt;Posts_model-&gt;slug_count($slug, null);

    update()方法改成这样:

    $slugcount = $this-&gt;Posts_model-&gt;slug_count($slug, $id);

    这是 slug_count:

    // Count the slugs in the posts table
    public function slug_count($slug, $id){
        $this->db->select('count(*) as slugcount');
        $this->db->from('posts');
        $this->db->where('slug', $slug);
        // if its an update
        if ($id != null) {
            $this->db->where('id !=', $id);
        }
        $query = $this->db->get();
        return $query->row(0)->slugcount;
    }
    

    【讨论】:

    • 函数slug_count($slug) 也用在 Posts 控制器的 create() 方法中。会不会受影响?
    • 是的。您还需要将 id var 传递给 slug_count 并检查它是否是新帖子。我猜如果它是新的,则 var 的 id 将是 null 所以将第二个包装在 if ($id != null) $this-&gt;db-&gt;where('id !=', $id);
    • 效果很好。你似乎真的很擅长使用 Codeigniter。请尝试回复this question。谢谢!
    【解决方案2】:
    // Update post
    public function update_post($id, $post_image, $slug) {
        $data = [
            'title' => $this->input->post('title'),
            'slug' => $slug,
            'description' => $this->input->post('desc'),
            'content' => $this->input->post('body'),
            'post_image' => $post_image,
            'cat_id' => $this->input->post('category'),
            'updated_at' => date('Y-m-d H:i:s')
        ];
    
        $this->db->where('id', $id);
        $query = $this->db->get('title');
    
        $count_row = $query->num_rows();
    
        if ($count_row > 0) {
    
            return FALSE; 
         } else {
    
            return $this->db->update('posts', $data); 
         }
    
    }
    

    【讨论】:

    • 我已经有 slug 数了:$slugcount = $this-&gt;Posts_model-&gt;slug_count($slug);.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 2019-03-18
    • 1970-01-01
    • 2021-05-23
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多