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

家住魔仙堡 提交于 2019-12-08 08:19:15

问题


The question title is the most explicit I could think of, but here's a use case/example for clarity's sake:

Say I define the following route to show an article:

Route::get('article/{slug}/{id}', 'ArticleController@show');

...

class ArticleController extends BaseController {

    public function show($id)
    {
        return View::make('article')->with('article', Article::find($id));
    }

}

This won't work, as show will misake the $id parameter with the $slug parameter. Is there a way to pass only the $id parameter to the show method?


回答1:


I dont know if you still look for solution or not, but as I had the same problem and I didn't like these solutions, I did this:

in the your ArticleController you overload the callAction($method, $parameters) method, this is a method in Laravel controller class, so it looks like this:

public function callAction($method, $parameters)
{
        unset($parameters['id']);
        unset($parameters['slug']);

        return parent::callAction($method, $parameters);
}

after this you ca easily do this:

public function show($id)
{
    return View::make('article')->with('article', Article::find($id));
}



回答2:


You can certainly "ignore" parameters with Laravel -- i.e. make them optional -- by adding a question mark after their name:

Route::get('article/{slug?}/{id?}', 'ArticleController@show');

Note that you are limited by PHPs way of handling optional function arguments: the leftmost arguments cannot be optional if you have required ones to the right.

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

I do agree with comments above saying it might not be entirely logical to do so. You will need either slug or id to lookup your article in the database, but at the same time you'd hope only of them would suffice to find the exact same article.

If you really want to have an optional slug in order to make your URLs more "crawlable", SEO-firendly, memorable or what have you, here's a suggestion, building from the example above:

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

    ...
}

I see no reason why anyone would try to access a slug-less URL, but that may be up to you and what you're trying to do with your app. This way at least you'd make the slug "optional", while making sure everyone ends up in the same spot with the full URL.




回答3:


It's possible to manually call controller functions:

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


来源:https://stackoverflow.com/questions/24789577/is-it-possible-to-reorder-or-ignore-parameters-in-controller-routes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!