在 Core 之外使用 Symfony2 验证器注解

Posted

技术标签:

【中文标题】在 Core 之外使用 Symfony2 验证器注解【英文标题】:Use Symfony2 Validator Annotations outside of Core 【发布时间】:2015-09-25 02:09:57 【问题描述】:

如何配置 Symfony2 Validator 以在 Core 之外使用注解?

在核心中,您将执行以下操作:

$container->loadFromExtension('framework', array(
  'validation' => array(
    'enable_annotations' => true,
  ),
));

取自:http://symfony.com/doc/2.0/book/validation.html#configuration

现在为了使验证工作,规则是在方法 loadValidatorMetadata(ClassMetadata $metadata) 中设置的,它可以工作,但我更喜欢注释。

带有验证注释的示例实体和用于设置验证规则的替代 php 方法:

<?php

namespace Foo\BarBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints as Assert;


/**
 * @ORM\Entity(repositoryClass="Foo\BarBundle\Entity\Repository\FooRepository")
 * @ORM\Table(name="foo")
 */
class Foo 


    /**
     * @ORM\Column(type="integer", name="bar")
     * @Assert\Type(
     *     type="integer",
     *     message="The value  value  is not a valid  type ."
     * )
     */
    protected $bar;


    public static function loadValidatorMetadata(ClassMetadata $metadata)
    
        $metadata->addPropertyConstraint('bar', new Assert\Type(array(
            'type'    => 'integer',
            'message' => 'The value  value  is not a valid  type .',
        )));
        

更新 1

现在的问题似乎是注释没有正确自动加载。

我将注释加载到命名空间中:

\Doctrine\Common\Annotations\AnnotationRegistry
::registerAutoloadNamespace("Symfony\Component\Validator\Constraints\\", __DIR__.'/vendor/symfony/validator');

然后,当它尝试自动加载注释时,它会查找不存在的 /vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php。该文件实际上位于/vendor/symfony/validator/Constraints/Length.php

我可以创建一个registerLoader(),但宁愿修复代码。当在 Symfony2 Core 中使用 Validator 时,文件位置是正确的。

如何使其正确自动加载或让 composer 将 Symfony2 组件安装到与核心相同的位置?

【问题讨论】:

我已经将 Symfony\Validator 集成到 Nette\DI,你可以find some inspiration there。 你看过 github.com/symfony/Validator#usage 吗,向下移动到注释。请不要忘记下载需要依赖的学说/注释库等。 【参考方案1】:

您需要使用 AnnotationRegistry 注册 Autoloader,因此无论何时需要供应商/自动加载,例如 bootstrap.php,请添加 registerLoader()。

//Composer libraries
$loader = require_once 'vendor/autoload.php';

\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader([$loader, 'loadClass']);

结果证明解决方案非常简单。

【讨论】:

【参考方案2】:

接受的答案提供了解决方案,但没有对失败进行任何解释。

原因很简单。 Doctrine\Common\Annotations\AnnotationRegistry 提供的默认注解加载器仅处理 PSR-0 命名空间,而 Symfony\Component\Validator\Constraints 是 PSR-4 命名空间。因此,加载器无法加载类。使用 AnnotationRegistry::registerLoader 方法注册 composer auloader 可以解决问题,因为该自动加载器处理 PSR-4 命名空间。

您可以参考此问题以获取有关 PSR-0 和 PSR-4 差异的更多详细信息:What is the difference between PSR-0 and PSR-4?

【讨论】:

由于我偶然发现了这个问题,我想补充一下,Doctrine 默认情况下不会在它自己的库之外自动加载 any 注释。默认注释引擎指定一个文件,指示可以使用哪些注释(因此 PSR-0 或 PSR-4 并没有真正的问题)。见Doctrine Configuration.php

以上是关于在 Core 之外使用 Symfony2 验证器注解的主要内容,如果未能解决你的问题,请参考以下文章

在 Symfony2 中使用自定义身份验证提供程序

Symfony2 - 如何验证控制器中的电子邮件地址

Symfony2:记住我身份验证时无效的 CSRF 令牌

Symfony2 自定义身份验证:用户登录但未通过身份验证

Symfony2 基于两个字段的表单验证

我需要在 symfony2 中使用哪个类进行自定义身份验证