Php 是否可以重新排序或忽略控制器路由中的参数?
问题标题是我能想到的最明确的,但为了清晰起见,这里有一个用例/示例: 假设我定义以下路径来显示文章:Php 是否可以重新排序或忽略控制器路由中的参数?,php,laravel,laravel-routing,Php,Laravel,Laravel Routing,问题标题是我能想到的最明确的,但为了清晰起见,这里有一个用例/示例: 假设我定义以下路径来显示文章: Route::get('article/{slug}/{id}', 'ArticleController@show'); ... class ArticleController extends BaseController { public function show($id) { return View::make('article')->with(
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
方法?您当然可以使用Laravel“忽略”参数,即使其成为可选参数,方法是在其名称后添加问号:
Route::get('article/{slug?}/{id?}', 'ArticleController@show');
请注意,处理可选函数参数的方式受到PHPs的限制:如果右边有必需的参数,则最左边的参数不能是可选的
// 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
在数据库中查找您的文章,但同时您希望只有其中一个能够找到完全相同的文章
如果你真的希望有一个可选的slug,以使你的URL更“可爬行”,搜索引擎优化火热,令人难忘,或你有什么,这里有一个建议,从上面的例子建设:
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的原因,但这可能取决于你和你的应用程序。通过这种方式,您至少可以将slug设置为“可选”,同时确保每个人都使用完整的URL到达同一位置。可以手动调用控制器功能:
Route::get('article/{slug}/{id}', function($slug, $id)
{
return App::make('ArticleController')->show($id);
});
我不知道你是否还在寻找解决方案,但由于我有同样的问题,我不喜欢这些解决方案,我做了如下: 在your
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));
}
你能不能把路线改成
'article/{id}
?是的,但是如果用户输入/article/some title/12345
,这比/article/12345
更容易记住,我就失去了额外的好处(例如,看看StackOverflow的URL)。那为什么不把你的show函数改成公共函数show($slug,$id)
?如果没有传入文章,如何在控制器中通过slug获取文章?在这里,你的选择非常有限,你要么想让子弹进入路线,要么不想。请注意,我的问题是“是否有可能……”。我知道有解决办法。