首页 > 解决方案 > Laravel 8 - 根据匹配(产品,类别,页面)调用多个控制器的友好 url - 如何设计它?

问题描述

我想建立一条路线来捕捉干净的 seo 友好 url 并调用正确的控制器来显示页面。例子:

https://mypage.com/some-friendly-url-separated-with-dashes [PageController]
https://mypage.com/some-cool-eletronic-ipod [ProductController]
https://mypage.com/some-furniture-drawers [CategoryController]

所以我有应用程序路线:

Route::get('/{friendlyUrl}', 'RouteController@index');

每个友好的 url 都是唯一的 url(字符串),因此页面/产品/类别之间没有重复。url 之间也没有模式——它们可以是 seo 中使用的任何字符串(只有文本加上破折号/有时是参数)。

构建一个 db 表是否明智,该表将所有 url 保留在适当的位置,并提供信息调用 (url | controller_name | action_name) - 例如。

另一个问题是 - 如何根据使用的 url 调用不同的控制器?(对于上面的示例-> RouteController 捕获友好的 url - 在 db 表中找到匹配项-> 然后调用正确的控制器)

非常感谢您的帮助。祝你今天过得愉快

标记

标签: laravellaravel-routing

解决方案


你可以采取两种方法来解决这个问题。

积极主动的:

web.php

$slugs = Product::pluck('slug');
foreach ($slugs as $slug) {
    Route::get($slug, 'ProductController@index');
}

$slugs = Category::pluck('slug');
foreach ($slugs as $slug) {
    Route::get($slug, 'CategoryController@index');
}

$slugs = Page::pluck('slug');
foreach ($slugs as $slug) {
    Route::get($slug, 'PagesController@index');
}

然后您可以通过例如在适当的控制器中确定产品

$actualItem = Product::where('slug', request()->path())->first();

这种方法的缺点是所有路由都在每个请求上注册,即使它们没有被使用,这意味着你在每个请求上都访问数据库来填充它们。此外,使用此方法时无法缓存路由。

反应性:

在这种方法中,您使用回退路线:

web.php

Route::fallback(function (Request $request) {
   if (Page::where('slug', $request->path())->exists()) {
        return app()->call([ PageController::class, 'index' ]);
   }
   if (Category::where('slug', $request->path())->exists()) {
        return app()->call([ CategoryController::class, 'index' ]);
   }
   if (Product::where('slug', $request->path())->exists()) {
        return app()->call([ ProductController::class, 'index' ]);
   }
   abort(404);
});

推荐阅读