ZF-Rest $event->getRouteMatch() 在扩展 RestController 时为 null
ZF-Rest $event->getRouteMatch() is null when extending RestController
我在我的项目中使用 zf-rest
composer 包。
这是我的资源文件中的 create
方法。
public function create($data)
{
var_dump($e->getRouteMatch()->getParams());
// all URL params are listed here with the correct values
die();
}
我现在已将 RestController
扩展到 CustomRestController
并添加了
'controller_class' => CustomRestController::class
到配置文件。
现在,var_dump($event->getRouteMatch());
null
在资源类中。
在public function onBootstrap(MvcEvent $e)
中,使用
$eventManager->attach(
MvcEvent::EVENT_ROUTE,
function($e) {
// I can still read `$e->getRouteMatch()->getParams()`
}
);
非常感谢任何有关如何处理此问题的建议。
更新答案:
根本问题是RestParametersListener
。它使用 FQCN,例如:
$listener = $events->attach(
RestController::class,
// more params
);
所以扩展 RestController 会导致这些 attach
/detach
调用来避免使用新控制器。
一个干净的修复是将 RestParametersListener
扩展到 CustomRestParametersListener
并更改内部控制器 类。
扩展后,我还在 module.config.php
中添加了它:
'service_manager' => [
'invokables' => [
'ZF\Rest\RestParametersListener' => CustomRestParametersListener::class,
],
// ...
]
初步回答:
在 zf-rest 开发团队修复问题 102 和 103 之前找到解决方法
在我的 CustomRestController
:
try {
$this->manuallyInjectRouteMatch(); // added this line
$value = $this->getResource()->create($data);
} catch (Throwable $e) {
return $this->createApiProblemFromThrowable($e);
} catch (Exception $e) {
return $this->createApiProblemFromException($e);
}
其中:
/**
* By using this factory instead of the default one and by creating a CastorRestController
* instead of RestController, the routeMatch property is "lost".
* Manually injecting it so we have access to it inside the *Resource class
*/
private function manuallyInjectRouteMatch()
{
$r = new \ReflectionProperty(Resource::class, 'routeMatch');
$r->setAccessible(true);
$r->setValue($this->getResource(), $this->getEvent()->getRouteMatch());
}
此外,manuallyInjectRouteMatch
也需要为其他 REST 方法调用
我在我的项目中使用 zf-rest
composer 包。
这是我的资源文件中的 create
方法。
public function create($data)
{
var_dump($e->getRouteMatch()->getParams());
// all URL params are listed here with the correct values
die();
}
我现在已将 RestController
扩展到 CustomRestController
并添加了
'controller_class' => CustomRestController::class
到配置文件。
现在,var_dump($event->getRouteMatch());
null
在资源类中。
在public function onBootstrap(MvcEvent $e)
中,使用
$eventManager->attach(
MvcEvent::EVENT_ROUTE,
function($e) {
// I can still read `$e->getRouteMatch()->getParams()`
}
);
非常感谢任何有关如何处理此问题的建议。
更新答案:
根本问题是RestParametersListener
。它使用 FQCN,例如:
$listener = $events->attach(
RestController::class,
// more params
);
所以扩展 RestController 会导致这些 attach
/detach
调用来避免使用新控制器。
一个干净的修复是将 RestParametersListener
扩展到 CustomRestParametersListener
并更改内部控制器 类。
扩展后,我还在 module.config.php
中添加了它:
'service_manager' => [
'invokables' => [
'ZF\Rest\RestParametersListener' => CustomRestParametersListener::class,
],
// ...
]
初步回答:
在 zf-rest 开发团队修复问题 102 和 103 之前找到解决方法
在我的 CustomRestController
:
try {
$this->manuallyInjectRouteMatch(); // added this line
$value = $this->getResource()->create($data);
} catch (Throwable $e) {
return $this->createApiProblemFromThrowable($e);
} catch (Exception $e) {
return $this->createApiProblemFromException($e);
}
其中:
/**
* By using this factory instead of the default one and by creating a CastorRestController
* instead of RestController, the routeMatch property is "lost".
* Manually injecting it so we have access to it inside the *Resource class
*/
private function manuallyInjectRouteMatch()
{
$r = new \ReflectionProperty(Resource::class, 'routeMatch');
$r->setAccessible(true);
$r->setValue($this->getResource(), $this->getEvent()->getRouteMatch());
}
此外,manuallyInjectRouteMatch
也需要为其他 REST 方法调用