php - Symfony2 注释继承

标签 php symfony annotations

在我的项目中,我有一个 BaseController 类,它实现了我所有 Controller 使用的几种方法。

现在我想为该基类添加@QueryParam。我的类(class)看起来像这样:

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

    }
}

现在我有了从基本 Controller 扩展而来的实际 Controller :

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");
    }
}

不幸的是,Symfony2 似乎没有从父类(super class)继承@QueryParam 注释,因为调用$paramFetcher->get("start") 导致异常“No @QueryParam/@RequestParam configuration for parameter 'start '”。

有没有什么方法可以使注解继承起作用,或者有任何其他解决方案,这样我就不必将@QueryParam 添加到我的每个 Controller 中了吗?

最佳答案

FosRestBundle 中没有这方面的功能,因此您必须根据需要重写它的一部分,更具体地说是类 FOSRestBundle/中的方法 getParamsFromMethod请求/ParamReader(参见 source code here)。

这可以通过包继承来完成。

首先,子类 FOSRestBundle\Request\ParamReader 在你的一个 bundle 中,例如YourSite\RestBundle\Request\MyParamReader 并通过加载父方法的注释并将它们与当前方法的注释合并来覆盖 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。您需要覆盖服务定义,其中参数读取器被列为依赖项。这是包覆盖/继承发挥作用的地方,请参阅 this Symfony2 article .

服务定义位于Resources/config/request.xml文件中(参见source code here),FOSRestBundle\Request\ParamReader的依赖>FOS\RestBundle\Request\ParamFetcher

因此您必须覆盖Resources/config/request.xml 文件。为此,按照上面的文章,注册您的包并将 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>

这是未经测试的,但它应该有效。

关于php - Symfony2 注释继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30425978/

相关文章:

iOS - MKMapView - 错误注释

java - 如果覆盖的保留策略是源,运行时多态性如何工作

php - 数组内爆后插入失败

javascript - 显示 2 后在 slider 中显示 1 张图片

php - ajax返回成功但mysql数据库未更新

symfony - 如何防止Symfony2转义html

postgresql - 设计简单的推送通知系统

java - Java 自定义注释有哪些合适的用途?

php - 无法访问序列化数据

PHP:使用准备好的语句并防止 SQL 注入(inject)与转义