Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony2注释继承_Php_Symfony_Annotations - Fatal编程技术网

Php Symfony2注释继承

Php Symfony2注释继承,php,symfony,annotations,Php,Symfony,Annotations,在我的项目中,我有一个BaseController类,它实现了我所有控制器使用的几个方法 现在我想为这个基类添加@QueryParam。我的班级是这样的: class DoctrineRESTQueryController extends FOSRestController { /** * @QueryParam(name="start",default=0) * @QueryParam(name="limit",default=null) */ p

在我的项目中,我有一个BaseController类,它实现了我所有控制器使用的几个方法

现在我想为这个基类添加@QueryParam。我的班级是这样的:

class DoctrineRESTQueryController extends FOSRestController
{
    /**
     * @QueryParam(name="start",default=0)
     * @QueryParam(name="limit",default=null)
     */
    public function getQueryResponseAction (ParamFetcher $paramFetcher) {

    }
}
现在我有了我的实际控制器,它从我的基本控制器扩展而来:

class DefaultController extends DoctrineRESTQueryController {

    /**
     * Retrieves all SI Prefixes in the database
     *
     * @Routing\Route("/siprefix", defaults={"method" = "get","_format" = "json"})
     * @Routing\Method({"GET"})
     * @ApiDoc(output="array<PartKeepr\SiPrefixBundle\Entity\SiPrefix>")
     *
     * @View()
     *
     * {@inheritdoc}
     */
    public function getQueryResponseAction(ParamFetcher $paramFetcher) {
         $paramFetcher->get("start");
    }
}
class DefaultController扩展DoctrineRESTQueryController{
/**
*检索数据库中的所有SI前缀
*
*@Routing\Route(“/siprefix”,默认值={“method”=“get”,“_format”=“json”})
*@Routing\Method({“GET”})
*@ApiDoc(output=“array”)
*
*@View()
*
*{@inheritardoc}
*/
公共函数getQueryResponseAction(ParamFetcher$ParamFetcher){
$paramefetcher->get(“开始”);
}
}
不幸的是,Symfony2似乎没有从超类继承@QueryParam注释,因为调用$paramefetcher->get(“start”)会导致异常“No@QueryParam/@RequestParam configuration for parameter'start”


是否有任何方法可以使注释继承工作,或任何其他解决方案,这样我就不必将@QueryParam添加到我的每个控制器中?

FosRestBundle中没有此功能,因此您必须根据需要覆盖其中的部分,更具体地说,类
FOSRestBundle/Request/ParamReader
中的方法
getParamsFromMethod
(请参阅)

这可以通过bundle继承完成

首先,在一个bundle(例如,
YourSite\RestBundle\Request\MyParamReader
)中创建子类
FOSRestBundle\Request\ParamReader
,并通过加载父方法的注释并将其与当前方法的注释合并来覆盖
getParamsFromMethod

namespace YourSite\RestBundle\Request\MyParamReader;

use FOSRestBundle\Request\ParamReader;

class MyParamReader extends ParamReader
{
    public function getParamsFromMethod(\ReflectionMethod $method)
    {
        $parentParams = array();
        $params = parent::getParamsFromMethod($method);

        // This loads the annotations of the parent method
        $declaringClass = $method->getDeclaringClass();
        $parentClass = $declaringClass->getParentClass();

        if ($parentClass && $parentClass->hasMethod($method->getShortName())) {
            $parentMethod = $parentClass->getMethod($method->getShortName());
            $parentParams = parent::getParamsFromMethod($parentMethod);
        }

        return array_merge($params, $parentParams);
    }
}
如有必要,可以修改代码以处理深层继承层次结构

现在,您应该告诉
FOSRestBundle
使用
YourSite\RestBundle\Request\MyParamReader
类,而不是
FOSRestBundle\Request\ParamReader
。您需要重写服务定义,其中参数读取器作为依赖项列出。这就是bundle覆盖/继承发挥作用的地方,请参阅

服务定义位于
Resources/config/request.xml
文件(请参阅),
FOSRestBundle\request\ParamReader
FOS\RestBundle\request\paramefetcher
的依赖项

因此,您必须覆盖
Resources/config/request.xml
文件。要做到这一点,请按照上面的文章注册您的bundle并声明
FOSRestBundle
为其父:

namespace YourSite\RestBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class YourSiteRestBundle extends Bundle
{
     public function getParent()
     {
          return 'FOSRestBundle';
     }
}
创建文件
YourSite\RestBundle\Resources\config\request.xml
以将
YourSite\RestBundle\request\MyParamReader
添加为依赖项:

<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <parameters>
        <parameter key="fos_rest.request.param_fetcher.class">FOS\RestBundle\Request\ParamFetcher</parameter>
        <parameter key="your_site_rest.request.param_fetcher.reader.class">YourSite\RestBundle\Request\MyParamReader</parameter>
    </parameters>
    <services>
        <service id="fos_rest.request.param_fetcher" class="%fos_rest.request.param_fetcher.class%" scope="request">
            <argument type="service" id="your_site.request.param_fetcher.reader"/>
            <argument type="service" id="request"/>
            <argument type="service" id="fos_rest.violation_formatter"/>
            <argument type="service" id="validator" on-invalid="null"/>
        </service>
        <service id="your_site.request.param_fetcher.reader" class="%your_site_rest.request.param_fetcher.reader.class%">
            <argument type="service" id="annotation_reader"/>
        </service>
    </services>
</container>

FOS\RestBundle\Request\ParamFetcher
YourSite\RestBundle\Request\MyParamReader

这是未经测试的,但应该可以使用。

非常好的解决方案,谢谢!也许有人在symfony3中寻找相同的.yml配置,以下应该可以工作:

parameters:
    fos_rest.request.param_fetcher.class: FOS\RestBundle\Request\ParamFetcher
    your_site_rest.request.param_fetcher.reader.class: YourSiteBundle\Request\MyParamReader

services:
    fos_rest.request.param_fetcher:
        class: %fos_rest.request.param_fetcher.class%
        arguments: ['@service_container', '@your_site.request.param_fetcher.reader', '@request_stack', '@?validator']
        scope: request
    your_site.request.param_fetcher.reader:
        class: %your_site.request.param_fetcher.reader.class%
        arguments: ['@annotation_reader']

你太棒了!一个小错误:自定义阅读器应该检查父方法是否确实存在:if($parentClass&&$parentClass->hasMethod($method->getShortName()){$parentMethod=$parentClass->getMethod($method->getShortName());$parentParams=parent::getParamsFromMethod($parentMethod);}返回数组_merge($params,$parentParams);}