【发布时间】:2016-06-16 12:58:28
【问题描述】:
我需要根据文章标题生成独特的 slug。对于匹配的蛞蝓,我想在末尾附加一个数字以使它们独一无二。我根据我发现的其他工作制作了这个函数:
static function slugify($title)
{
$slug = str_slug($title, '-');
//THIS IS THE PROBLEMATIC LINE:
$common = Article::whereRaw("slug RLIKE '^{$slug}(-[0-9]+)?$'")->orderBy('slug', 'desc')->get();
$count = count($common);
if( $count > 0 ){
$last = $common[0];
$broken = explode('-', $last->slug);
$num = $broken[count($broken)-1];
$num = intval($num) + 1;
return $slug.'-'.$num;
} else
return $slug.'-1';
}
问题: 如您所见,我尝试使用 Laravel 的 str_slug 函数生成新的 slug,该函数会将字符串转换为 slug 形式。然后我尝试从数据库中查询现有的 slug,将它们降序排列(高 > 低),并在有序集中取最高的。 问题是 MySQL 当然将它们排序为字符串,因此 slug-title-9 实际上会被认为高于 slug-title-10 因为它将它们作为字符排序并且不是基于最后数字的值。我怎样才能使这项工作?有没有办法根据最后一个数字来订购它们,还是我走错了方向?
我想避免的解决方案:
我见过其他实现,人们一次查询所有类似的 slug,计算它们,然后将 count+1 附加到新 slug 的末尾。 这很糟糕,因为如果你删除一些文章,总数量会减少,新的 sl 可能会与旧的冲突。
我见过一个实现,一个人将 1 附加到 slug 的末尾并检查它是否存在。如果它存在,他们将改为追加 2 并尝试检查它是否存在,等等,直到他们找到例如不存在的 slug-title-9 。 IMO 这很糟糕,因为您给数据库带来了不必要的压力。
我需要一个体面的解决方案,因为我正在从事的项目有可能经常遇到匹配的 slug。
【问题讨论】:
-
为什么不能简单地附加文章 ID?它保证是独一无二的,不会让您头疼。
-
@TadasPaplauskas 哇......因为我没想到......谢谢:)
-
@TadasPaplauskas 你能帮我理解一下吗?当我调用诸如 PDO::lastInsertId 之类的东西时,它会返回在此会话中插入的最后一个 id 吗?因此,例如,如果两个用户同时调用一个函数来插入一行,那么它就不会返回错误的 id,对吧?