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获取文章?在这里,你的选择非常有限,你要么想让子弹进入路线,要么不想。请注意,我的问题是“是否有可能……”。我知道有解决办法。