Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Codeigniter博客应用程序:避免slug的重复输入错误_Php_Codeigniter_Slug_Slugify - Fatal编程技术网

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

Php Codeigniter博客应用程序:避免slug的重复输入错误,php,codeigniter,slug,slugify,Php,Codeigniter,Slug,Slugify,我正在Codeigniter 3.1.8和Bootstrap 4中开发一个基本的博客应用程序。posts表有一个slug列,我打算用它来创建SEO友好的URL 因为每个帖子的slug都是其URL的一部分,slug列当然是唯一的。我使用CI的url\u title()方法将文章标题变为slug: 鉴于上述情况,当两篇文章的标题完全相同(“谁喜欢蝴蝶?”)时,显然会出现问题: 我需要一种方法,使重复的标题后产生一个“编号”的鼻涕虫:“谁爱蝴蝶1”等,如果必要的话 Codeigniter 3文档没有为

我正在Codeigniter 3.1.8和Bootstrap 4中开发一个基本的博客应用程序。
posts
表有一个
slug
列,我打算用它来创建SEO友好的URL

因为每个帖子的slug都是其URL的一部分,
slug
列当然是唯一的。我使用CI的
url\u title()
方法将文章标题变为slug:

鉴于上述情况,当两篇文章的标题完全相同(“谁喜欢蝴蝶?”)时,显然会出现问题:

我需要一种方法,使重复的标题后产生一个“编号”的鼻涕虫:“谁爱蝴蝶1”等,如果必要的话


Codeigniter 3文档没有为其
url\u title()
方法提供这样的方法?有什么方法可以修改它或替代它吗?

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

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

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

在启用查询生成器的情况下,第一种方法是使用内置的
表单\u验证
,检查您的slug是否符合
是否唯一
,如果不唯一,则稍微更改它并重新检查,直到验证通过。尽管
form\u validation
主要用于验证和清理用户输入,但您几乎可以将其用于任何事情

另一种方法是,在插入之前,通过向生成的slug追加一个nonce、一个随机数或一些其他唯一参数,始终确保在第一次尝试时获得唯一的slug。例如:

$slug = url_title($this->input->post('title'), 'dash', TRUE).strtotime(date('Y-m-d H:i:s'));
以上可能是最简单的方法,只要不在同一秒创建两个标题完全相同的帖子,这种方法就行。这将(几乎)完全减少碰撞的机会

第三种解决方案稍微麻烦一点,将涉及使用
$slug=url\u title($this->input->post('title'),'dash',TRUE)计算基本slug然后:

1.-将slug传递给一个简单的数据库查询(在控制器中或模型中,由您选择)

如果slug是唯一的,则返回0,如果之前有一个条目,则返回1,依此类推

之后,您可以选择: 第一次创建slug时,附加“-0”或“-1”(取决于什么对SEO最有利) 第二次附加“-1”或“-2”(取决于上一次定义的内容) 等等等等

例如,你可以用

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

这行吗?

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

Posts_模型中模型:

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

这是一个函数,它将为任何表创建始终唯一的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');

据我所知,您的问题是数据库中存在重复密钥
url\u title
只需将字符串转换为url格式,而不必处理数据库。您必须编写一个自定义函数来检查数据库上是否存在
slug
。一旦出现slug,您就是一个简单、有创意的解决方案。不过,搜索引擎优化并不友好。只是好奇。。。你觉得SEO友好吗?我正在休息,也许我可以帮你找出这一个超过了第三个非本地的选择,我相信它更符合你所期待的最终结果,它工作得很好。查看我如何在应用程序中应用您的解决方案。谢谢!请帮帮我。谢谢
// 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;
}
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');