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

时间:2014-07-16 20:00:07

标签: php laravel laravel-routing

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

假设我定义了以下路线来展示文章:

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方法?

3 个答案:

答案 0 :(得分:6)

我不知道你是否还在寻找解决方案,但由于我遇到了同样的问题而且我不喜欢这些解决方案,我这样做了:

在你的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));
}

答案 1 :(得分:4)

你当然可以忽略" 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在数据库中查找您的文章,但与此同时,您只希望他们只需找到完全相同的文章。

如果你真的想要一个可选的slug,以便让你的网址更容易被抓取,#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));
    }

    ...
}

我认为没有理由为什么有人会尝试访问无网页的网址,但这可能取决于您以及您尝试使用您的应用做的事情。这样至少你可以制作slug" optional",同时确保每个人都在完整网址的同一位置。

答案 2 :(得分:4)

可以手动调用控制器功能:

Route::get('article/{slug}/{id}', function($slug, $id)
{
    return App::make('ArticleController')->show($id);
});