【发布时间】:2017-08-11 10:39:24
【问题描述】:
因此,我们的目标是制作自定义注释,该注释也可以将参数插入方法中。因此,经过数小时寻找解决方案并尝试使其发挥作用后,我从未找到完整的解决方案,因此我将一些我能找到的东西放在一起,我的代码如下所示:
public function onKernelController(FilterControllerEvent $event)
{
if (!is_array($controller = $event->getController())){
return;
}
$request = $event->getRequest();
$content = $request->getContent();
$data = json_decode($content,true);
$reflectionObject = new \ReflectionObject($controller[0]);
$reflectionMethod = $reflectionObject->getMethod($controller[1]);
$methodAnnotation = $this->reader->getMethodAnnotation($reflectionMethod, CheckRequest::class);
if(!$methodAnnotation){
return;
}
$propertyName = $methodAnnotation->getName();
try{
if ($request->getContentType() !== 'json' ) {
throw new ControlerNotAvailableException();
}
if(empty($content)){
throw new ControlerNotAvailableException();
}
if(empty($data) || !array_key_exists('type', $data)) {
throw new ControlerNotAvailableException();
}
}catch(ControlerNotAvailableException $e){
}
foreach($reflectionMethod->getParameters() as $param){
if($param->getName() !== $propertyName){
continue;
}
if($request->attributes->has($propertyName)){
return;
}
$request->attributes->set($propertyName, $data);
}
}
我的注释类看起来像这样:
class CheckRequest
{
private $name;
public function __construct($options)
{
if(isset($options['value'])){
$options['name'] = $options['value'];
unset($options['value']);
}
foreach ($options as $key => $value){
if(!property_exists($this, $key)){
throw new \InvalidArgumentException(sprintf('Property %s does not exist', $key));
}
$this->$key = $value;
}
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
}
所以为了让这件事更清楚一点。我有一个监听器事件,它监听 kernel.controller 事件。在那个侦听器中,我正在运行一些小问题,例如内容类型是否为 json 等...此外,ControllerNotAvailableEception 是我制作的自定义异常,所以不要让您感到困惑。然后我们进入我的问题所在的部分,即以下内容:
foreach($reflectionMethod->getParameters() as $param){
if($param->getName() !== $propertyName){
continue;
}
if($request->attributes->has($propertyName)){
return;
}
$request->attributes->set($propertyName, $data);
}
现在,只是为了澄清一下,这是可行的,并且可以正确地在方法参数中注入值,所以如果我在我的控制器中输入这样的内容:
/**
*@CheckRequest(name = "data")
*/
public function createAction(array $data){
}
这行得通,并且填充了 $data 参数。
最后,当我解释了这一切时,我现在可以问我的问题了。
这是执行此操作的正确方法,还是有一些通过注释注入参数值的“标准化”方法,您能给我举个例子吗?我知道@ParamConverter 注释做了这些事情,但我不知道它是如何将值绑定到引擎盖下的参数的。
提前感谢您的回答!
【问题讨论】:
-
尝试编辑您的问题,以便简短地说出您想要实现的目标。特别是这些参数是什么以及为什么要注入它们。这将增加您获得有用答案的机会。
-
您好,感谢您的建议。我想注入参数的原因是我可以减少控制器中的冗余,假设我有 5 个控制器,在这些控制器中,第一行代码是 $data = json_decode($request->getContent( ));所以我不想每次在我的请求中得到一个 Json 时都写那行代码。我想自动将它绑定到方法的参数。我希望这能澄清我的意图:)
-
你说“这行得通”。你真的试过了吗?乍一看,这似乎不像你拥有的那样工作。
-
是的,我试过了,它工作正常。对不起我生疏的英语。你能告诉我其他更合适的方法吗?
标签: php symfony annotations doctrine