Skip to content

Loading…

DCOM-75: remove leading backslash from class name before comparing to namespace in annotation autoloading #675

Closed
doctrinebot opened this Issue · 2 comments

2 participants

@doctrinebot

Jira issue originally created by user goriol:

I am figuring a problem with Symfony Validator constraints (I use annotations to define the constraint rules).

As I don't use Symfony's framework, I create the validator service by myself.
Somewhere in its factory, I put the following code:

AnnotationRegistry::registerAutoloadNamespaces(array(
    '\Symfony\Component\Validator\Constraints' => APPLICATION_ROOT . '/library'
));

Then, in my entities, I have annotations such as:

use Symfony\Component\Validator\Constraints as Assert;

class Author {
    /****
     * @Assert\NotBlank()
     */
    protected $name;
}

In this configuration, I get the following error:
{quote}[Semantical Error] The annotation "@Symfony\Component\Validator\Constraints\NotBlank"
in property Domain\Entity\Author::$name does not exist, or could not be auto-loaded.{quote}

I was able to trace it down to the Doctrine\Common\Annotations\AnnotationRegistry#loadAnnotationClass($class) where we can find the following test:

    if (strpos($class, $namespace) === 0) {
        require ...;
    }

which means "if the namespace can be found at the beginning of the FQCN, require it".
But those namespaces come from "use" statements where there is no leading backslash.
That's why the test fails.

Christophe Coevoet answered:
bq. you should remove the leading backslash. Fully qualified class names used as string don't include it in PHP.

Benjamin Eberlei suggested to remove the leading backslash before comparing the class to the namespace.
I would follow Benjamin suggestion and would like to add a comment about leading backslashes:

When I add a use statement to my code for a class, I can then use its alias to get an instance of that class.

use Doctrine\ORM\Mapping\ClassMetadata;
...
$metadata = new ClassMetadata();

The same is true with:

use Doctrine\ORM\Mapping as Foo;
...
$metadata = new Foo\ClassMetadata();

This is not a fully qualified class name.
In that sense, I do understand such an annotation: @ORM\Entity.

But I find the syntax of a fully-qualified annotation (@My\Annotation\Whatever) erroneous (or at least counter-intuitive) as it doesn't start with a backslash.

@doctrinebot

Comment created by @guilhermeblanco:

Your referred problem is an internal namespace => directory mapping.
Strings in PHP already represent FQCN and that's why you shouldn't have a leading backslash in your string.

This has nothing to do with annotations.

@doctrinebot

Issue was closed with resolution "Invalid"

@doctrinebot doctrinebot closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.