Codeigniter博客应用程序:避免重复输入错误

时间:2018-10-12 18:55:51

标签: php codeigniter slug slugify

我正在使用Codeigniter 3.1.8和Bootstrap 4中的基本博客应用posts表中有一个slug列,我打算在制作SEO时使用该列。友好的网址。

由于每个帖子的信息都将成为其URL的一部分,因此slug列当然是 unique 。我使用CI的url_title()方法来从帖子标题中删除弹头

$slug = url_title($this->input->post('title'), 'dash', TRUE);

鉴于上述情况,很明显,当两个帖子的标题完全相同(“谁爱蝴蝶?”)时,就会出现问题:

Duplicate entry 'who-loves-a-butterfly' for key 'slug'

如果需要,我需要一种方法来使重复的标题帖子生成一个“编号的”条:“ who-loves-a-butterfly-1”,依此类推。

Codeigniter 3文档的url_title()方法没有提供这种方法吗?有什么方法可以修改它或替代它吗?

4 个答案:

答案 0 :(得分:1)

您可以使用很多创造性的方法。这完全取决于您的个人喜好。

第一个启用了查询生成器的用户将使用内置的form_validation并检查您的子弹是否符合is_unique,如果不是,请稍加更改并重新检查直到验证通过。即使form_validation主要用于验证和清除用户输入,您也可以将其用于几乎任何事情。

另一种方法是始终确保在首次尝试时获得唯一的子段,方法是在插入之前在生成的子段上附加随机数或随机数或其他一些唯一的参数。例如:

$slug = url_title($this->input->post('title'), 'dash', TRUE).strtotime(date('Y-m-d H:i:s'));

只要没有在相同的第二秒钟创建两个标题完全相同的帖子,以上可能是最简单的方法。这样可以(几乎)完全减少碰撞的机会。

第三个解决方案比较麻烦,它将涉及使用$slug = url_title($this->input->post('title'), 'dash', TRUE);计算基础段,然后:

1.-将子句传递给简单的数据库查询(您可以选择在控制器中还是在模型内部)

$this->db->select('count(*) as slugcount');
$this->db->from('your_table');
$this->db->where('slug', $slug);

$query = $this->db->get();
return $query->row(0)->slugcount;

如果该子弹确实是唯一的,则将返回0,如果以前有一个条目,则将返回1,依此类推。

然后选择: 首次创建子弹时,请附加“ -0”或“ -1”(取决于最适合SEO的内容) 第二次添加“ -1”或“ -2”(取决于您在上一个定义中的定义) 等等等等

例如,您可以使用

$slug = $slug."-".$slugcount;

那行得通吗?

答案 1 :(得分:0)

我通常在模型中使用自定义函数sanitize()创建该唯一的条目: 请阅读代码注释,因为它记录了流程

function sanitize($string,$table='posts'){
    // sanitize string, remove Latin chars like 'ç ' and add - instead of white-space
    // based on: http://stackoverflow.com/a/2103815/2275490
    $str= strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8')), '-'));
    // check how often header exists in table "posts"
    // add counted suffix to pretty_url if already exists
    $query = $this->db  ->where('slug', $string)
                        ->get($table);
    if($query->num_rows()>0) 
        $str=$str.'-'.$query->num_rows(); // allways returns the latest number for same slug

    return $str;                    
}

答案 2 :(得分:0)

这是我的博客应用程序中应用的完整解决方案:

Posts_model 模型中:

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;
}

public function create_post($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,
        'author_id' => $this->session->userdata('user_id'),
        'cat_id' => $this->input->post('category'),
        'created_at' => date('Y-m-d H:i:s')
    ];
    return $this->db->insert('posts', $data);
}

帖子控制器中:

// 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;
}

答案 3 :(得分:0)

这是一个可以为任何表创建始终唯一的 slug 的函数。 在模型中

function get_unique_slug($slug,$table)
{
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$this->db->select('count(*) as slugcount');
$this->db->from($table);
$this->db->where('slug like', $slug.'%');

$query = $this->db->get();
if($query->row(0)->slugcount>0)
{
    return $slug.'-'.$query->row(0)->slugcount;
}
else
{
    return $slug;
}
}

在控制器中

$slug = $this->crud_model->get_unique_slug($slug,'category');