Use Symfony2 Validator Annotations outside of Core

2020-08-02 06:27发布

How do you configure Symfony2 Validator to use annotations outside of Core?

In core you would do the following:

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

Taken from: http://symfony.com/doc/2.0/book/validation.html#configuration

For now to make validation work the rules are set within the method loadValidatorMetadata(ClassMetadata $metadata), it works but I prefer annotations.

Example Entity with validation annotations and alternative php method to set validation rules:

<?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 }}.',
        )));
    }    
}

Update 1

The issue now seems to be that the annotations are not being autoloaded correctly.

I load the annotations in to the namespace with:

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

Then when it tries to autoload the annotations it looks for /vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php which does not exist. The file is actually located at /vendor/symfony/validator/Constraints/Length.php

I could create a registerLoader() but would rather fix the code. When using Validator within Symfony2 Core that file location would be correct.

How do I make it autoload correctly or get composer to install Symfony2 components to the same location as core?

2条回答
仙女界的扛把子
2楼-- · 2020-08-02 07:03

You need to register the Autoloader with AnnotationRegistry, so where ever you require vendor/autoload, for example bootstrap.php add the registerLoader().

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

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

Turns out the solution is quite straight forward.

查看更多
▲ chillily
3楼-- · 2020-08-02 07:12

The accepted answer provides a solution without giving any explaination regarding the failure.

The reason is simple. The default annotation loader which is provided by the Doctrine\Common\Annotations\AnnotationRegistry only handle PSR-0 namespaces, while the Symfony\Component\Validator\Constraints is a PSR-4 namespace. Thus, the loader fail to load the class. Registering the composer auloader with the AnnotationRegistry::registerLoader method solves the problem because that autoloader handle the PSR-4 namespaces.

You can refer to this question to get more detaits about PSR-0 and PSR-4 differences: What is the difference between PSR-0 and PSR-4?

查看更多
登录 后发表回答