【问题标题】:Multiple routes defaults to controller in LaravelLaravel 中的多个路由默认为控制器
【发布时间】:2014-11-03 07:35:18
【问题描述】:

我希望能够通过短链接访问文章,例如 articles/ID,但我也希望通过完整链接 articles/ID/category/slug 到达那里。但我无法让以下工作:

// Route file:
Route::pattern('id', '[0-9]+');
Route::pattern('cat', '^(?!create).*');
Route::pattern('slug', '^(?!edit).*');
Route::get('articles/{id}/{cat?}/{slug?}', ['as' => 'articles.show', 'uses' => 'ArticlesController@show']);

// Controller file:
public function show($id, $cat = null, $slug = null)
{
    dd('1: ' . $cat . ' | 2:' . $slug);
}

下面的链接articles/28/ullam/vel-repellendus-aut-est-est-esse-fugiat给出了结果:

string(53) "1: ullam/vel-repellendus-aut-est-est-esse-fugiat | 2:"

我不明白为什么它没有被拆分,如果我在路由定义中删除 ? 就可以了。

我已经尝试过这个解决方案https://stackoverflow.com/a/21865488/3903565 并且有效,但在针对控制器时无效。为什么?

更新;我最终重新安排了路线文件:

Route::pattern('id', '[0-9]+');

// Articles
Route::get('articles/create', ['as' => 'articles.create', 'uses' => 'ArticlesController@create']);
Route::get('articles/edit/{id}', ['as' => 'articles.edit', 'uses' => 'ArticlesController@edit']);
Route::get('articles/{id}/{category?}/{slug?}', ['as' => 'articles.show', 'uses' => 'ArticlesController@show']);
Route::get('articles/{category?}', ['as' => 'articles.index', 'uses' => 'ArticlesController@index']);
Route::resource('articles', 'ArticlesController', ['only' => ['store', 'update', 'destroy']]);

【问题讨论】:

    标签: laravel laravel-4 laravel-routing


    【解决方案1】:

    那是你唯一的路线吗?或者你也有不同的指向要显示?我刚刚添加了这条路线作为我的第一条路线:

    Route::get('articles/{id}/{cat?}/{slug?}', function($id, $cat, $slug)
    {
        dd($id.': ' . $cat . ' | 2:' . $slug);
    });
    

    得到了这个结果:

    28: ullam | 2:vel-repellendus-aut-est-est-esse-fugiat
    

    更改路线的顺序,将第一条作为最具体的路线,将最后一条作为最通用的路线。此外,如果您有任何模式,它们可能会干扰您的结果。

    看起来某些模式和可选参数(?)有问题,所以如果你这样做

    Route::pattern('id', '[0-9]+');
    Route::pattern('cat', '^(?!create).*');
    Route::pattern('slug', '^(?!edit).*');
    
    Route::get('articles/{id}/{cat}/{slug}', function($id, $cat, $slug)
    {
        dd($id.': ' . $cat . ' | 2:' . $slug);
    });
    

    它会正常工作的。我的建议是不要过多地重用路由,如果您有特定的路由,请为其创建一个路由命令并将其添加到最通用的路由之前:

    Route::get('articles/{id}/create', function($id)
    {
        dd('this is the create route');
    });
    
    Route::get('articles/{id}/{cat}/{slug}', function($id, $cat, $slug)
    {
        dd($id.': ' . $cat . ' | 2:' . $slug);
    });
    

    与寻找正则表达式模式并尝试在其中找到自己的方式的复杂性相比,创建新路由的成本较低。在项目上拥有新的合作者,甚至是为你未来的自己,越简单越好。

    在 Laravel 4.3 中,您将可以访问路由缓存,这使得路由几乎立即被触发。

    【讨论】:

    • 嗯,实际上是我的模式阻止了这一点。我有以下内容; Route::pattern('id', '[0-9]+'); Route::pattern('slug', '^(?!edit).*'); Route::pattern('cat', '^(?!create).*'); 不明白他们为什么会干扰这个 URL:articles/22/corrupti/tempora-autem-numquam-in-quis 但他们会。编辑:这是导致问题的原因:Route::pattern('cat', '^(?!create).*');
    • 所以它比/{cat?}/ 变量中的实际匹配更多?我认为它确保输入的cat 变量没有以create 开头。
    • 很奇怪的行为,这里也有问题。已编辑。
    • 谢谢,我最终重新排列了最具体的路线。
    【解决方案2】:

    问题仅在于前瞻模式。

    您需要$ 和不包括/ 的类才能使其工作。

    所以他们在这里:

    Route::pattern('id', '[0-9]+');
    Route::pattern('cat', '^(?!create$)[^/]*');
    Route::pattern('slug', '^(?!edit$)[^/]*');
    
    Route::get('articles/{id}/{cat?}/{slug?}', function($id, $cat, $slug)
    {
        dd($id.': ' . $cat . ' | 2:' . $slug);
    });
    

    【讨论】:

    • 这解释了为什么我的路线不起作用,所以我会接受这个作为答案,即使我最终没有使用 catslug 的模式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 2023-03-13
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多