这是我问题的要点。我正在 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
。