我尝试过以下代码。
$post->title = $request->title;
$post->body = $request->body;
$post->slug = str_slug($post->title,'%');
代码运行良好但现在我的帖子具有相同的标题,因此它的抛出错误因为它在db中设置为唯一。 有什么方法可以得到另一个slug?
答案 0 :(得分:3)
如果您正面临一个slug colision,在这种情况下,最好的方法是在最后一个例子中添加一个额外的整数:
mysite.dev/my-post
mysite.dev/my-post-1
为此,您可以使用check this生成slug
如果你想自己做,那么在模型中添加slugattribute
public function setSlugAttribute($value) {
if (static::whereSlug($slug = str_slug($value))->exists()) {
$slug = $this->incrementSlug($slug);
}
$this->attributes['slug'] = $slug;
}
因此setSlugAtrribute将始终检查给定模型的slug是否存在,如果是,那么它将按照我上面的意思递增slug,只需调用以下方法。
public function incrementSlug($slug) {
$original = $slug;
$count = 2;
while (static::whereSlug($slug)->exists()) {
$slug = "{$original}-" . $count++;
}
return $slug;
}
基本上我们总是检查数据库中是否存在slug,如果是,那么我们使用一个访问器来通过最后添加一个整数来改变slug,这样你就永远不会遇到slug重复问题。
答案 1 :(得分:0)
创建我们自己的函数,该函数可从任何标题生成唯一的子弹。看一下代码,这很清楚。
来自this link的参考代码。
<?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();
}
}
最后。我们在Laravel中创建了一个独特的子弹。
localhost:8000/kwee-dev
localhost:8000/kwee-dev-1
答案 2 :(得分:0)
我遇到了同样的问题,那就是我的解决方案:
/**
* Create a slug from title
* @param string $title
* @return string $slug
*/
protected function createSlug(string $title): string
{
$slugsFound = $this->getSlugs($title);
$counter = 0;
$counter += $slugsFound;
$slug = str_slug($title, $separator = "-", app()->getLocale());
if ($counter) {
$slug = $slug . '-' . $counter;
}
return $slug;
}
/**
* Find same listing with same title
* @param string $title
* @return int $total
*/
protected function getSlugs($title): int
{
return Listing::select()->where('title', 'like', $title)->count();
}
答案 3 :(得分:0)
使用以下两个软件包之一,只需几行代码即可轻松解决此常见问题:
https://github.com/spatie/laravel-sluggable
只需安装运行的软件包即可:
composer require spatie/laravel-sluggable
然后将以下代码添加到您的模型中:
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
class Post extends Model
{
use HasSlug;
public function getSlugOptions() : SlugOptions
{
return SlugOptions::create()
->generateSlugsFrom('title')
->saveSlugsTo('slug');
}
或替代:
https://github.com/cviebrock/eloquent-sluggable
您可以输入以下内容进行安装:
composer require cviebrock/eloquent-sluggable
然后添加到您的模型中:
use Cviebrock\EloquentSluggable\Sluggable;
class Post extends Model
{
use Sluggable;
/**
* Return the sluggable configuration array for this model.
*
* @return array
*/
public function sluggable()
{
return [
'slug' => [
'source' => 'title'
]
];
}
}
答案 4 :(得分:0)
几个月前,我搜索了自动化 slug 创建的便捷解决方案,并发现了 Taner Fejzulovski 使用 Laravel 的 Mutator 做出的有趣决定。
但是,当我开始检查和调试时,我明白代码还没有完全完成。 因此,我根据自己的需要和对检查的理解对其进行了更新和重构。
我使用了递归方法来完整检查数据库中先前创建的 slug。也许它对你和其他人也有用!
/**
* Set the proper slug attribute.
*
* @param string $value
* @return mixed
*/
public function setSlugAttribute($value)
{
if(static::whereSlug($slug = Str::slug($value))->exists())
{
if(static::whereSlug($slug)->get('id')->first()->id !== $this->id){
$slug = $this->incrementSlug($slug);
if(static::whereSlug($slug)->exists()){
return $this->setSlugAttribute($slug);
}
}
}
$this->attributes['slug'] = $slug;
}
/**
* Increment slug
*
* @param string $slug
* @return string
**/
public function incrementSlug($slug)
{
// Get the slug of the created post earlier
$max = static::whereSlug($slug)->latest('id')->value('slug');
if (is_numeric($max[-1])) {
return preg_replace_callback('/(\d+)$/', function ($matches) {
return $matches[1] + 1;
}, $max);
}
return "{$slug}-2";
}