Laravel 5.2 中一个路由中的多个路由参数模式

Posted

技术标签:

【中文标题】Laravel 5.2 中一个路由中的多个路由参数模式【英文标题】:Multiple route argument patterns in one route in Laravel 5.2 【发布时间】:2016-08-30 15:07:17 【问题描述】:

你好,

首先,我真的试着用谷歌搜索这个。但似乎不可能在一条路由中多次使用路由参数模式。我的目标是在路由定义中对 /resource/uuid/subresource/uuid 等路由进行参数验证,而无需在控制器中手动检查这些参数。

假设我们有:

$router->pattern('uuid', '[0-9a-f]8-[0-9a-f]4-[0-9a-f]4-[0-9a-f]4-[0-9a-f]12');

非常适合像这样的路线

$router->get('/payment/uuid', 'Payments@payment');
$router->get('/users/uuid', 'Users@get');
//etc..

但是

$router->get('/users/uuid/order/uuid', 'Controller@someStuff');

抛出错误:

"Route pattern "/users/uuid/order/uuid" cannot reference variable name "uuid" more than once."

似乎合法。但我只想通过正则表达式 DRY 验证参数,而下面的其他方法也不起作用:

$router->get('/users/userId/order/orderId', 'Controller@someStuff')
        ->where(['userId' => 'uuid', 'orderId' => 'uuid']); 
// or

$router->get('/users/userId:uuid/order/orderId:uuid', 'Controller@someStuff');

// ..and vice versa

唯一有效的是:

$router->get('/users/userId/order/orderId', 'Controller@someStuff')
        ->where(['userId' => '[0-9a-f]8-[0-9a-f]4-[0-9a-f]4-[0-9a-f]4-[0-9a-f]12', 'orderId' => '[0-9a-f]8-[0-9a-f]4-[0-9a-f]4-[0-9a-f]4-[0-9a-f]12']);

...但我真的不想走这条路。这实际上是它起作用的唯一方法。

有谁知道一些技巧,如何多次应用路由参数模式?

谢谢,任何帮助将不胜感激...

【问题讨论】:

【参考方案1】:

Laravel 似乎不支持命名路由模式。我以前不得不处理这种事情,我发现这是一种可靠的做事方式:

app/Providers 中打开RouterServiceProvider.php 并将以下内容添加到您的boot() 方法中:

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @param  \Illuminate\Routing\Router  $router
 * @return void
 */
public function boot(Router $router)

    $uuidPattern = '[0-9a-f]8-[0-9a-f]4-[0-9a-f]4-[0-9a-f]4-[0-9a-f]12';

    $router->pattern('userId', $uuidPattern);
    $router->pattern('orderId', $uuidPattern);
    $router->pattern('anotherUuid', $uuidPattern); // Just an example - delete this line!

    parent::boot($router);

基本上,您可以在其中添加所有路由器模式,它们将可用于您的路由。它们都在一个地方,因此很容易记住它们在哪里需要更新它们,并且您可以为多个参数重复使用相同的模式。

【讨论】:

感谢您的回复。实际上,我在Router::boot 方法中有模式定义。是的,这也是一种方式。但是想象一下,API 会有几十个端点,你不想为每个"<entityName>Id" 定义 uuid 模式。方法可能类似于将resrouceIdsubresourceId 定义为uuids,但我仍然觉得宇宙有些不好。我可能会打开一个问题/功能请求并让您知道。 我认为你是对的,这也让我思考,我打算提交 PR 以允许命名参数模式。我在构建的 API 中遇到了这个确切的问题,该 API 使用 UUID 获取大量资源。 打开了issue..我们会看到 结论 - 它不受支持,可能永远不会。因此,我接受这是一种解决方法...【参考方案2】:

在 Laravel 7.x 中

您应该在 RouteServiceProvider 的引导方法中定义这些模式

public function boot() 
    $uuidPattern = '[0-9a-f]8-[0-9a-f]4-[0-9a-f]4-[0-9a-f]4-[0-9a-f]12';

    Route::pattern('userId', $uuidPattern);
    Route::pattern('orderId', $uuidPattern);

    parent::boot();

上述方法应用于使用该参数名称的所有路由

路线,

Route::get('/users/userId/order/orderId', function () 
    // Only executed if userId and orderId accepts given regular expression($uuidPattern)...
);

【讨论】:

以上是关于Laravel 5.2 中一个路由中的多个路由参数模式的主要内容,如果未能解决你的问题,请参考以下文章

如何使用where关键字检查Laravel 5.2路由中的状态参数?

提交表单时使用路由参数传递变量Laravel 5.2

Laravel 5.2 带有可变参数的命名路由用法

如何在Laravel 5.2中将表单数据作为路由参数传递

使用ajax从控制器调用函数的新路由或其他方式? Laravel 5.2,阿贾克斯

只能访问 Laravel 5.2 中的 / 路由