Php Laravel 5.6-路由模型与默认控制器绑定
我正在使用Laravel构建一个购物应用程序,其中每个产品的URL必须保持简洁 而不是使用以下permalink结构:(这是常见的,但不合适)Php Laravel 5.6-路由模型与默认控制器绑定,php,laravel,binding,controller,routes,Php,Laravel,Binding,Controller,Routes,我正在使用Laravel构建一个购物应用程序,其中每个产品的URL必须保持简洁 而不是使用以下permalink结构:(这是常见的,但不合适) www.example.com/products/{product slug} 我想使用这个permalink结构: www.example.com/{product slug} 为了实现这一点,我在路由文件中使用隐式路由模型绑定: Route::get( '{product}', function ( App\Product $product ) {
www.example.com/products/{product slug}
我想使用这个permalink结构:
www.example.com/{product slug}
为了实现这一点,我在路由文件中使用隐式路由模型绑定:
Route::get( '{product}', function ( App\Product $product ) {
return view( 'product' ); // this works, but is not what I want
});
我正在覆盖我的产品
模型中的查找行为:
class Product extends Model
{
public function getRouteKeyName()
{
return 'slug'; // use the 'product.slug' column for look ups within the database
}
}
现在,根据Laravel的文件:
Laravel自动解析路由或控制器操作中定义的雄辩模型,其类型提示变量名称与路由段名称匹配。
因此,我知道Laravel将把{product}
变量与存储在我的数据库中的产品相匹配,如果找不到,则返回404响应
这一切对我来说都很有意义
然而 每个产品页都是唯一的,因此在路由与
{product}
匹配后,{product}
对象需要传递给控制器进行进一步处理
如果要保持隐式模型绑定,如何将此路由传递给控制器?将路由指向控制器函数 这将是您的路线(我将控制器命名为
ProductController
,并将其指向show
函数,但您可以根据自己的喜好对两者进行重命名):
这将在您的ProductController中:
public function show(Request $request, \App\Product $product)
{
// Do stuff with $product
// Return view and pass it the $product variable
return view('product', compact('product'));
}
指向控制器功能的路由 这将是您的路线(我将控制器命名为
ProductController
,并将其指向show
函数,但您可以根据自己的喜好对两者进行重命名):
这将在您的ProductController中:
public function show(Request $request, \App\Product $product)
{
// Do stuff with $product
// Return view and pass it the $product variable
return view('product', compact('product'));
}
为了回答我自己的问题,我认为我找到了一个结合了我最初的方法和回应的伟大解决方案: 这一想法值得称赞 事实证明,您还可以通过将雄辩的模型作为依赖项传递,在控制器内执行隐式模型绑定:
/* App/Http/Controllers/ProductController.php */
/**
* Get the Product object.
*
* @param App\Models\Product
*/
public function show( Product $product )
{
return view( 'product', compact( 'product' ) );
}
即使我们现在使用控制器引用模型,Laravel仍然会自动解析模型。事实上,该行为在文档中有明确定义:
Laravel自动解析routes或中定义的雄辩模型
控制器操作其类型提示变量名称与路由匹配
段名称。
我第一次读的时候一定是漏掉了那些词
现在,为了设置
{product slug}
路由(按照我想要的方式),您必须设置模型和路由定义,如下所示:
/* App/Models/Product.php */
class Product extends Model
{
/**
* Get the route key for the model.
*
* @return string
*/
public function getRouteKeyName()
{
return 'slug';
}
}
如前所述,重写getRouteKeyName()
方法将使Laravel使用数据库中的slug
列而不是其id
列(默认值)搜索产品
在routes文件中,我们仍然将参数命名为{product}
(而不是{product slug}
),因为参数的名称必须与雄辩模型的名称匹配
使用此配置,在以下位置发出请求:
www.example.com/{product slug}
如果提供的{product slug}
与数据库中存储的页面匹配,则将返回产品页面。如果未找到产品,将返回404 not found响应
但是,由于我们将此路由绑定到基本路径/
,这意味着客户端请求的每个URL都将通过此配置传递
要避免此问题,请确保路由定义在路由文件中的顺序正确(从最高优先级到最低优先级),并在发生冲突时使用验证 为了回答我自己的问题,我想我已经找到了一个结合我最初的方法和回应的很好的解决方案: 这一想法值得称赞 事实证明,您还可以通过将雄辩的模型作为依赖项传递,在控制器内执行隐式模型绑定:
/* App/Http/Controllers/ProductController.php */
/**
* Get the Product object.
*
* @param App\Models\Product
*/
public function show( Product $product )
{
return view( 'product', compact( 'product' ) );
}
即使我们现在使用控制器引用模型,Laravel仍然会自动解析模型。事实上,该行为在文档中有明确定义:
Laravel自动解析routes或中定义的雄辩模型
控制器操作其类型提示变量名称与路由匹配
段名称。
我第一次读的时候一定是漏掉了那些词
现在,为了设置
{product slug}
路由(按照我想要的方式),您必须设置模型和路由定义,如下所示:
/* App/Models/Product.php */
class Product extends Model
{
/**
* Get the route key for the model.
*
* @return string
*/
public function getRouteKeyName()
{
return 'slug';
}
}
如前所述,重写getRouteKeyName()
方法将使Laravel使用数据库中的slug
列而不是其id
列(默认值)搜索产品
在routes文件中,我们仍然将参数命名为{product}
(而不是{product slug}
),因为参数的名称必须与雄辩模型的名称匹配
使用此配置,在以下位置发出请求:
www.example.com/{product slug}
如果提供的{product slug}
与数据库中存储的页面匹配,则将返回产品页面。如果未找到产品,将返回404 not found响应
但是,由于我们将此路由绑定到基本路径/
,这意味着客户端请求的每个URL都将通过此配置传递
要避免此问题,请确保路由定义在路由文件中的顺序正确(从最高优先级到最低优先级),并在发生冲突时使用验证 应用程序中的其他页面如何?
www.example.com/login
页面也会意外匹配并传递到此cont