Symfony - 从未导入注释
Symfony - The annotation was never imported
我正在使用 Symfony 框架并打算将自动文档引擎添加到我的项目的 RESTful api。
经过一番搜索,我找到了 apidoc 引擎 (http://apidocjs.com/)。它的工作非常简单:你必须为你的每个控制器添加一些注释 RESTful api 并且将生成文档。
注解示例为:
/**
* @Route("/api/dictionary_list/{userId}/{sessionKey}", name="api/dictionary_list")
* @api {get} /api/dictionary_list/{userId}/{sessionKey} 01. Values list (ids) for all system dictionaries
* @apiName Dictionary list
* @apiGroup Dictionary
*
* @apiParam {Integer} userId User's ID received in authorization request
* @apiParam {String} sessionKey Session key received in authorization request
*
* @apiSuccess {Integer} parcelStatuses The name of current dictionary
* @apiSuccess {String} itemId Item id which used in requests
* @apiSuccess {String} itemName Item name
*/
public function dictionaryListAction($userId=null, $sessionKey=null)
{
...
}
如您所见,apidoc 的注释与 Symfony 中路由的注释相同。
顺便说一句,在生产环境中它工作正常,但在开发环境中我得到像
这样的异常
[Semantical Error] The annotation "@apiName" in method AppBundle\Controller\Api\apiDictionaryController::dictionaryListAction() was never imported.
有什么方法可以解决这个问题并告诉 Symfony 必须忽略 apidoc 的注释吗?
Symfony 使用 doctrine/annotations 包来解析注解。当它遇到未被列入黑名单的未知注解时,它会抛出异常。
您可以将其他注释列入黑名单,请参阅 Doctrine docs - Ignoring missing exceptions:
use Doctrine\Common\Annotations\AnnotationReader;
AnnotationReader::addGlobalIgnoredName('api');
AnnotationReader::addGlobalIgnoredName('apiParam');
AnnotationReader::addGlobalIgnoredName('apiGroup');
AnnotationReader::addGlobalIgnoredName('apiSuccess');
我会把它放在 app/autoload.php 中,因为它是全局设置。
您可以使用 IgnoreAnnotation
注释告诉 Docrine 注释 reader 在您的控制器中跳过此注释。为此,只需将注释添加 @IgnoreAnnotation("Annotation")
到 class.
的 class 文档注释中
你的情况:
/**
* @IgnoreAnnotation("apiName")
* @IgnoreAnnotation("apiGroup")
* @IgnoreAnnotation("apiParam")
* @IgnoreAnnotation("apiSuccess")
*/
class ActionController extends Controller
/**
* @Route("/api/dictionary_list/{userId}/{sessionKey}", name="api/dictionary_list")
* @api {get} /api/dictionary_list/{userId}/{sessionKey} 01. Values list (ids) for all system dictionaries
* @apiName Dictionary list
* @apiGroup Dictionary
*
* @apiParam {Integer} userId User's ID received in authorization request
* @apiParam {String} sessionKey Session key received in authorization request
*
* @apiSuccess {Integer} parcelStatuses The name of current dictionary
* @apiSuccess {String} itemId Item id which used in requests
* @apiSuccess {String} itemName Item name
*/
public function dictionaryListAction($userId=null, $sessionKey=null)
{
...
}
您也可以考虑向 doctrine/annotations project to include this annotation as default skipped as this one.
公开一个 PR
希望对您有所帮助。
您必须导入路线:
使用Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
在 DI 容器编译期间读取注释,因此在 compiler pass 期间忽略 apidocs 注释可能是更好的主意。
示例:
<?php
namespace YourBundle\DependencyInjection;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class IgnoreApiDocsAnnotationsPass implements CompilerPassInterface {
public function process(ContainerBuilder $container) {
AnnotationReader::addGlobalIgnoredName('api');
AnnotationReader::addGlobalIgnoredName('apiDefine');
AnnotationReader::addGlobalIgnoredName('apiDeprecated');
AnnotationReader::addGlobalIgnoredName('apiDescription');
AnnotationReader::addGlobalIgnoredName('apiError');
AnnotationReader::addGlobalIgnoredName('apiErrorExample');
AnnotationReader::addGlobalIgnoredName('apiExample');
AnnotationReader::addGlobalIgnoredName('apiGroup');
AnnotationReader::addGlobalIgnoredName('apiHeader');
AnnotationReader::addGlobalIgnoredName('apiHeaderExample');
AnnotationReader::addGlobalIgnoredName('apiIgnore');
AnnotationReader::addGlobalIgnoredName('apiName');
AnnotationReader::addGlobalIgnoredName('apiParam');
AnnotationReader::addGlobalIgnoredName('apiParamExample');
AnnotationReader::addGlobalIgnoredName('apiPermission');
AnnotationReader::addGlobalIgnoredName('apiPrivate');
AnnotationReader::addGlobalIgnoredName('apiSampleRequest');
AnnotationReader::addGlobalIgnoredName('apiSuccess');
AnnotationReader::addGlobalIgnoredName('apiSuccessExample');
AnnotationReader::addGlobalIgnoredName('apiUse');
AnnotationReader::addGlobalIgnoredName('apiVersion');
}
}
我从 apidoc docs 获得了完整的注释列表。您需要使用
在您的包中注册编译器传递
<?php
namespace YourBundle;
use YourBundle\DependencyInjection\IgnoreApiDocsAnnotationsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class YourBundle extends Bundle {
public function build(ContainerBuilder $container) {
parent::build($container);
$container->addCompilerPass(new IgnoreApiDocsAnnotationsPass());
}
}
我正在使用 Symfony 框架并打算将自动文档引擎添加到我的项目的 RESTful api。
经过一番搜索,我找到了 apidoc 引擎 (http://apidocjs.com/)。它的工作非常简单:你必须为你的每个控制器添加一些注释 RESTful api 并且将生成文档。
注解示例为:
/**
* @Route("/api/dictionary_list/{userId}/{sessionKey}", name="api/dictionary_list")
* @api {get} /api/dictionary_list/{userId}/{sessionKey} 01. Values list (ids) for all system dictionaries
* @apiName Dictionary list
* @apiGroup Dictionary
*
* @apiParam {Integer} userId User's ID received in authorization request
* @apiParam {String} sessionKey Session key received in authorization request
*
* @apiSuccess {Integer} parcelStatuses The name of current dictionary
* @apiSuccess {String} itemId Item id which used in requests
* @apiSuccess {String} itemName Item name
*/
public function dictionaryListAction($userId=null, $sessionKey=null)
{
...
}
如您所见,apidoc 的注释与 Symfony 中路由的注释相同。
顺便说一句,在生产环境中它工作正常,但在开发环境中我得到像
这样的异常[Semantical Error] The annotation "@apiName" in method AppBundle\Controller\Api\apiDictionaryController::dictionaryListAction() was never imported.
有什么方法可以解决这个问题并告诉 Symfony 必须忽略 apidoc 的注释吗?
Symfony 使用 doctrine/annotations 包来解析注解。当它遇到未被列入黑名单的未知注解时,它会抛出异常。
您可以将其他注释列入黑名单,请参阅 Doctrine docs - Ignoring missing exceptions:
use Doctrine\Common\Annotations\AnnotationReader;
AnnotationReader::addGlobalIgnoredName('api');
AnnotationReader::addGlobalIgnoredName('apiParam');
AnnotationReader::addGlobalIgnoredName('apiGroup');
AnnotationReader::addGlobalIgnoredName('apiSuccess');
我会把它放在 app/autoload.php 中,因为它是全局设置。
您可以使用 IgnoreAnnotation
注释告诉 Docrine 注释 reader 在您的控制器中跳过此注释。为此,只需将注释添加 @IgnoreAnnotation("Annotation")
到 class.
你的情况:
/**
* @IgnoreAnnotation("apiName")
* @IgnoreAnnotation("apiGroup")
* @IgnoreAnnotation("apiParam")
* @IgnoreAnnotation("apiSuccess")
*/
class ActionController extends Controller
/**
* @Route("/api/dictionary_list/{userId}/{sessionKey}", name="api/dictionary_list")
* @api {get} /api/dictionary_list/{userId}/{sessionKey} 01. Values list (ids) for all system dictionaries
* @apiName Dictionary list
* @apiGroup Dictionary
*
* @apiParam {Integer} userId User's ID received in authorization request
* @apiParam {String} sessionKey Session key received in authorization request
*
* @apiSuccess {Integer} parcelStatuses The name of current dictionary
* @apiSuccess {String} itemId Item id which used in requests
* @apiSuccess {String} itemName Item name
*/
public function dictionaryListAction($userId=null, $sessionKey=null)
{
...
}
您也可以考虑向 doctrine/annotations project to include this annotation as default skipped as this one.
公开一个 PR希望对您有所帮助。
您必须导入路线:
使用Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
在 DI 容器编译期间读取注释,因此在 compiler pass 期间忽略 apidocs 注释可能是更好的主意。
示例:
<?php
namespace YourBundle\DependencyInjection;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class IgnoreApiDocsAnnotationsPass implements CompilerPassInterface {
public function process(ContainerBuilder $container) {
AnnotationReader::addGlobalIgnoredName('api');
AnnotationReader::addGlobalIgnoredName('apiDefine');
AnnotationReader::addGlobalIgnoredName('apiDeprecated');
AnnotationReader::addGlobalIgnoredName('apiDescription');
AnnotationReader::addGlobalIgnoredName('apiError');
AnnotationReader::addGlobalIgnoredName('apiErrorExample');
AnnotationReader::addGlobalIgnoredName('apiExample');
AnnotationReader::addGlobalIgnoredName('apiGroup');
AnnotationReader::addGlobalIgnoredName('apiHeader');
AnnotationReader::addGlobalIgnoredName('apiHeaderExample');
AnnotationReader::addGlobalIgnoredName('apiIgnore');
AnnotationReader::addGlobalIgnoredName('apiName');
AnnotationReader::addGlobalIgnoredName('apiParam');
AnnotationReader::addGlobalIgnoredName('apiParamExample');
AnnotationReader::addGlobalIgnoredName('apiPermission');
AnnotationReader::addGlobalIgnoredName('apiPrivate');
AnnotationReader::addGlobalIgnoredName('apiSampleRequest');
AnnotationReader::addGlobalIgnoredName('apiSuccess');
AnnotationReader::addGlobalIgnoredName('apiSuccessExample');
AnnotationReader::addGlobalIgnoredName('apiUse');
AnnotationReader::addGlobalIgnoredName('apiVersion');
}
}
我从 apidoc docs 获得了完整的注释列表。您需要使用
在您的包中注册编译器传递<?php
namespace YourBundle;
use YourBundle\DependencyInjection\IgnoreApiDocsAnnotationsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class YourBundle extends Bundle {
public function build(ContainerBuilder $container) {
parent::build($container);
$container->addCompilerPass(new IgnoreApiDocsAnnotationsPass());
}
}