如何在其他时间获得相同的帖子标题的独特slug?

Sus*_*ngh 11 php laravel

我已经尝试了以下代码。

 $post->title = $request->title;
        $post->body = $request->body;
        $post->slug  = str_slug($post->title,'%');
Run Code Online (Sandbox Code Playgroud)

代码运行良好,但现在我有相同标题的帖子,因此它抛出错误,因为它在 db 中设置为唯一。有什么办法可以得到另一个slug吗?

Leo*_*ent 14

如果您面临 slug 碰撞,在这种情况下,最好的方法是在最后的示例中添加一个额外的整数:

mysite.dev/my-post
mysite.dev/my-post-1
Run Code Online (Sandbox Code Playgroud)

为此,您可以使用一个包来生成一个 slug

如果你想自己做,那么在模型中添加 slugattribute

public function setSlugAttribute($value) {

    if (static::whereSlug($slug = str_slug($value))->exists()) {

        $slug = $this->incrementSlug($slug);
    }

    $this->attributes['slug'] = $slug;
}
Run Code Online (Sandbox Code Playgroud)

因此,setSlugAtrribute 将始终检查给定模型的 slug 是否存在,如果存在,那么它将通过简单地调用下面的方法来增加我上面提到的 slug。

public function incrementSlug($slug) {

    $original = $slug;

    $count = 2;

    while (static::whereSlug($slug)->exists()) {

        $slug = "{$original}-" . $count++;
    }

    return $slug;

}
Run Code Online (Sandbox Code Playgroud)

基本上,我们总是检查数据库中是否存在 slug,如果是,那么我们使用访问器通过在末尾添加一个整数来更改 slug,这样您将永远不会遇到 slug 重复问题。


小智 6

创建我们自己的函数,从任何标题生成独特的 slug。看一下代码就很清楚了。

来自此链接的参考代码。


<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;
class ProductController extends Controller
{
    public function store(Request $request)
    {
        $product = new Product;
        $product->title = $request->title;
        $product->slug = $this->createSlug($request->title);
        $product->save();
    }
    public function createSlug($title, $id = 0)
    {
        $slug = str_slug($title);
        $allSlugs = $this->getRelatedSlugs($slug, $id);
        if (! $allSlugs->contains('slug', $slug)){
            return $slug;
        }

        $i = 1;
        $is_contain = true;
        do {
            $newSlug = $slug . '-' . $i;
            if (!$allSlugs->contains('slug', $newSlug)) {
                $is_contain = false;
                return $newSlug;
            }
            $i++;
        } while ($is_contain);
    }
    protected function getRelatedSlugs($slug, $id = 0)
    {
        return Product::select('slug')->where('slug', 'like', $slug.'%')
        ->where('id', '<>', $id)
        ->get();
    }
}
Run Code Online (Sandbox Code Playgroud)

最后。我们在 Laravel 中创建了一个独特的 slug。

localhost:8000/kwee-dev
localhost:8000/kwee-dev-1
Run Code Online (Sandbox Code Playgroud)

  • 这是最完整、最有效的答案。另外,您可以使用 Str::slug($this-&gt;request-&gt;input('title'), '-'); 修改它 用于生成段头。 (2认同)