Symfony嵌套资源路由不传递id


Symfony nested resource routing not passing ids

这是我问题的要点。我正在 Symfony2 中创建一个 API,但我似乎无法让嵌套路由工作。

这行得通

api_v1_role_show:
    pattern:        /api/v1/roles/{roleId}
    defaults:       { _controller: rest_v1_roles_controller:showAction }
    methods:        [GET]

我可以通过做这样的事情来证明它是有效的

function showAction()
{
  var_dump(func_get_args()); // array(1)
}

这不起作用

api_v1_permission_post:
    pattern:        /api/v1/roles/{roleId}/permissions
    defaults:       { _controller: rest_v1_role_permissions_controller:createAction }
    methods:        [POST]

我最终得到这样的东西:

function createAction()
{
  //This should be array(1)
  var_dump(func_get_args()); // array()
}

我错过了什么?我已经尝试在网上查找了一个多小时,但我似乎找不到有关该主题的任何内容。我不得不怀疑这是否是行动后安全的事情。

REST 类结构

我们的应用程序中有很多休息端点。我们创建了一个 rest 类,允许我们快速添加称为 RestBaseController 的新端点,它看起来像这样:

class RestBaseController {
  protected $urlParams;
  public function showAction()
  {
     $this->urlParams = func_get_args();
     //Shows the resource based on ID now stored in $this->urlParams;
  }
  public function createAction()
  {
    $this->urlParams = func_get_args();
    $this->adjustParameters();
    //creates the resource from JSON body, essentially
  }
  protected function adjustParameters()
  {
    return null;
  }
}

然后是我遇到问题的类:

class RolePermissionsController extends RestBaseController
{
  protected function adjustParameters()
  {
    $role = $this->em()->getRepository('AppBundle:Role')
      ->find($this->urlParams[0]); //This will give me an error saying offset 0 does not exist.
    $this->roleId = $role->getRoleId();
  }
}

我的问题:我如何让嵌套的URL在Symfony中工作?

如果我没记错的话,symfony路由引入了反射和"命名参数"。

例如:route:/api/v1/roles/{roleId}/permissions/{otherId}

public fucntion action($otherId, $roleId) // position here is not important, important name

您还可以:

public fucntion action(Request $request, $otherId, $roleId)

第一个参数将被$request。

所以伙计,改变你的架构,直到为时不晚

最后,我找到了两种解决此问题的方法。德米特里指出,symfony使用反射和"命名参数"将路由分解为类似于function(Request $request, [ ...$uriExtractedName1, $uriExtractedName2])的可传递参数,这意味着我本来可以在

菲律宾比索 5.6+

RestBaseController.php

public function createAction(Request $request, ...$args)
{
  $this->request = $request;
  $this->urlParams = $args;
  //...
}

但是我目前正在处理早期版本的项目,所以我不得不做一些更简单的事情。

菲律宾比索 5.4

路由.yml

api_v1_permission_post:
    pattern:        /api/v1/roles/{parentId}/permissions
    defaults:       { _controller: rest_v1_role_permissions_controller:createAction }
    methods:        [POST]

RestBaseController.php

public function createAction($parentId = null)
{
  $this->parentId = $parentId;
  //...
}

这个解决方案的效果非常优雅。我不喜欢总是调用父 ID parentId但对于拥有非常小的控制器类来说,这是一个很小的代价。我意识到其他路由器总是可以工作的,因为我们称传递的id为id