Laravel 8 - 友好 url 根据匹配(产品、类别、页面)调用多个控制器 - 如何设计?
Laravel 8 - friendly url that call multiple controllers depending on match (products, categories, pages) - How to design it?
我想建立一个路线,捕捉干净的 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(字符串),因此 pages/products/categories 之间没有重复。 urls 之间也没有模式 - 它们可以是 seo 中使用的任何字符串(仅文本加破折号/有时是参数)。
构建一个数据库 table 以确保所有 url 都在适当的位置并提供调用信息(url | controller_name | action_name) - 例如。
另一个问题是 - 如何根据使用的 url 调用不同的控制器? (对于上面的例子 -> RouteController catch friendly urls - 在 db table 中找到匹配项 -> 然后调用正确的控制器)
非常感谢您的帮助。
祝你有美好的一天
马克
如果你像这样为每种类型使用前缀会更好:
https://mypage.com/pages/some-friendly-url-separated-with-dashes [PageController]
https://mypage.com/products/some-cool-eletronic-ipod [ProductController]
https://mypage.com/category/some-furniture-drawers [CategoryController]
然后为了实现这个,像这样创建三个路由
Route::get('pages/{friendlyUrl}', 'PageController@index');
Route::get('products/{friendlyUrl}', 'ProductController@index');
Route::get('category/{friendlyUrl}', 'CategoryController@index');
这些 URL 对 SEO 友好
您需要创建一个 table 调用 slug。
然后为每个页面、产品、类别创建一个唯一的 slug(可以自动生成或指定)。
slug 记录也有用于获取控制器和参数的列,例如:type
和 id
您可以采用两种方法。
主动:
在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);
});
我想建立一个路线,捕捉干净的 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(字符串),因此 pages/products/categories 之间没有重复。 urls 之间也没有模式 - 它们可以是 seo 中使用的任何字符串(仅文本加破折号/有时是参数)。
构建一个数据库 table 以确保所有 url 都在适当的位置并提供调用信息(url | controller_name | action_name) - 例如。
另一个问题是 - 如何根据使用的 url 调用不同的控制器? (对于上面的例子 -> RouteController catch friendly urls - 在 db table 中找到匹配项 -> 然后调用正确的控制器)
非常感谢您的帮助。 祝你有美好的一天
马克
如果你像这样为每种类型使用前缀会更好:
https://mypage.com/pages/some-friendly-url-separated-with-dashes [PageController]
https://mypage.com/products/some-cool-eletronic-ipod [ProductController]
https://mypage.com/category/some-furniture-drawers [CategoryController]
然后为了实现这个,像这样创建三个路由
Route::get('pages/{friendlyUrl}', 'PageController@index');
Route::get('products/{friendlyUrl}', 'ProductController@index');
Route::get('category/{friendlyUrl}', 'CategoryController@index');
这些 URL 对 SEO 友好
您需要创建一个 table 调用 slug。
然后为每个页面、产品、类别创建一个唯一的 slug(可以自动生成或指定)。
slug 记录也有用于获取控制器和参数的列,例如:type
和 id
您可以采用两种方法。
主动:
在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);
});