我建议您更改 URL,以便它们的一部分用于路由,一部分用于 SEO 目的。这就是我的意思:
/products/view/{product_id}/{category_name}/{category_name}/{etc}/{product_name}
/products/category/{category_id}/{category_name}/{category_name}/{etc}
这样做的优点是您可以忽略类别数量并不总是相同的事实。您的路由仅取决于 URL 的前几段。
Route::get('products/view/{id}/{seo-slug?}', array('as' => 'product', function($id, $seoSlug){
$product = Product::find($id);
// ...
}))->where('seo-slug', '.*');
Route::get('products/category/{id}/{seo-slug?}', array('as' => 'category', function($id, $seoSlug){
$category = Category::find($id);
// ...
}))->where('seo-slug', '.*');
现在,当涉及到生成链接时,仅使用 Laravel 辅助函数将很难。让我们创建我们自己的。一种方法是向产品和类别模型添加函数。 (您也可以编写一个独立于模型的函数,核心功能保持不变)
Product
public function getUrl(){
$categoryNames = array('cat1', 'cat2', 'cat3'); // use/create a function on the category model that uses recursion to determine all the categories of the tree
$seoSlug = implode('/', $categoryNames);
// ... maybe add other stuff to $seoSlug
return route('product', array($this->id, $seoSlug));
}
Category
public function getUrl(){
$categoryNames = array('cat1', 'cat2', 'cat3'); // use the same function as above
$seoSlug = implode('/', $categoryNames);
// ... maybe add other stuff to $seoSlug
return route('category', array($this->id, $seoSlug));
}
重定向“错误”的 URL
如果您愿意,您现在可以重定向具有错误 SEO slug 的 URL。这意味着也可以只输入:
/products/view/183
这也可以用作某种 URL 缩短,用于在电子邮件等中发送链接。
要验证 URL 然后重定向,您只需将当前 URL 与“新”生成的 URL 进行比较即可。像这样:
Route::get('products/view/{id}/{seo-slug?}', array('as' => 'product', function($id, $seoSlug){
$product = Product::find($id);
$productUrl = $product->getUrl()
if(Request::url() !== $productUrl){
return Redirect::to($productUrl);
}
// ...
}))->where('seo-slug', '.*');
Oh and 也祝你圣诞快乐!