是否可以重新排序或忽略控制器路由中的参数


Is it possible to reorder or ignore parameters in controller routes?

问题标题是我能想到的最明确的,但为了清晰起见,这里有一个用例/示例:

假设我定义了以下路由来显示一篇文章:

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) {}

我同意上面的评论,这样做可能不完全合乎逻辑。您将需要slugid在数据库中查找您的文章,但同时您希望只有它们中的一个足以找到完全相同的文章。

如果你真的想有一个可选的段塞,以使你的网址更"可抓取",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。