将ID转换为Slug的中间件

时间:2019-04-03 18:53:45

标签: php laravel

我已经完成了90%的网站,直到现在,它一直在页面之间传递圆形模型ID,例如:

http://website.domain/2/content/3

我正在使用绑定在web.php中的模型,如下所示:

Route::get('{post}/content/{comment}', 'ContentController@index');

这很好。

我想更改URL,以便它对用户/ SEO更友好,因此显示如下:

http://website.domain/hello-world/content/this-is-more

我知道我可以在控制器中为每个索引进行查找,但是我想知道在使用ID(例如中间件)时是否有一种更自动化的方法来转换URL,或者是否正在执行每次我都需要做查找的唯一方法吗?

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

您不需要通过中间件来做到这一点...

Eloquent的模型具有一种方法,该方法指示路由器将使用哪一列来查找绑定的模型,您只需要覆盖它即可。

帖子模型的示例:

namespace App\Models\Post;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Route;

class Post extends Model
{
    public function getRouteKeyName(): string {
        $identifier = Route::current()->parameters()['post'];

        if (!ctype_digit($identifier)) {
            return 'your-slug-col-name';
        }

        return 'id';
    }
}

这样,您的路线将可以使用id或slug ...

答案 1 :(得分:1)

一种简单的方法是使用显式模型绑定

在方法启动中的app / Providers / RouteServiceProvider.php中,您可以定义绑定

例如:

public function boot()
{
    Route::bind('postSlug',function($value){
       return Post::whereSlug($value)->firstOrFail();
    });
    Route::bind('commentSlug',function($value){
       return Comment::whereSlug($value)->firstOrFail();
    });

    parent::boot();
}

并在您的 Route.php 中:

Route::get('{postSlug}/content/{commentSlug}', 'ContentController@index');

希望这会有所帮助