问题标题是我能想到的最明确的,但为了清晰起见,这里有一个用例/示例:
假设我定义了以下路由来显示一篇文章:
Route::get('article/{slug}/{id}', 'ArticleController@show');
...
class ArticleController extends BaseController {
public function show($id)
{
return View::make('article')->with('article', Article::find($id));
}
}
这不起作用,因为show
会将$id
参数与$slug
参数混淆。是否有一种方法只传递$id
参数到show
方法?
我不知道你是否还在寻找解决方案,但由于我有同样的问题,我不喜欢这些解决方案,我这样做了:
在ArticleController
中重载callAction($method, $parameters)
方法,这是Laravel控制器类中的方法,所以它看起来像这样:
public function callAction($method, $parameters)
{
unset($parameters['id']);
unset($parameters['slug']);
return parent::callAction($method, $parameters);
}
之后,您可以轻松地执行以下操作:
public function show($id)
{
return View::make('article')->with('article', Article::find($id));
}
可以手动调用控制器函数:
Route::get('article/{slug}/{id}', function($slug, $id)
{
return App::make('ArticleController')->show($id);
});
你当然可以在Laravel中"忽略"参数——也就是让它们成为可选的——在它们的名字后面加一个问号:
Route::get('article/{slug?}/{id?}', 'ArticleController@show');
注意,php处理可选函数参数的方式是有限的:如果你在右边有必需的参数,那么最左边的参数就不能是可选的。
// Do
Route::get('article/{id}/{slug?}', 'ArticleController@show');
...
function show($id, $slug = null) {}
// Don't
Route::get('article/{slug?}/{id}', 'ArticleController@show');
...
function show($slug = null, $id) {}
我同意上面的评论,这样做可能不完全合乎逻辑。您将需要slug
或id
在数据库中查找您的文章,但同时您希望只有它们中的一个足以找到完全相同的文章。
如果你真的想有一个可选的段塞,以使你的网址更"可抓取",seo友好,难忘或你有什么,这里有一个建议,从上面的例子构建:
Route::get('article/{id}/{slug?}', array(
'as' => 'article.show',
'uses' => 'ArticleController@show'
));
...
function show($id, $slug = null)
{
$article = Article::find($id);
if (!$slug) {
return Redirect::route('article.show', array($id, $article->slug));
}
...
}
我看不出为什么有人会尝试访问一个没有段符的URL,但这可能取决于你和你想对你的应用做什么。这样至少你可以使段符"可选",同时确保每个人最终都在相同的位置与完整的URL。