I am trying to use Doctrine Common to create my own annotation. http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/annotations.html does not match https://github.com/doctrine/common because Call to undefined method Doctrine\\Common\\Annotations\\AnnotationReader::setDefaultAnnotationNamespace
and PHP Fatal error: Call to undefined method Doctrine\\Common\\Annotations\\AnnotationRegistry::registerAnnotationNamespace
. I checked the source, they are not there. According to git log they were removed a year ago.
I have a PSR-0 autoloader going (from Symfony). So I have a file where the PSR-0 loader expects:
namespace My\Test;
/**
* @Annotation
*/
class Foo {
}
Another class
namespace My\Annotated
/**
* @My\Test\Foo
*/
class Test {
}
Reader:
namespace My\Reader
use ReflectionClass;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use My\Test\Foo;
$reader = new AnnotationReader();
$reflectionClass = new ReflectionClass('My\\Annotated\\Test');
$classAnnotations = $reader->getClassAnnotations($reflectionClass);
var_dump($classAnnotations);
Gets: "[Semantical Error] The annotation "@My\\Test\\Foo" in class My\\Annotated\\test was never imported. Did you maybe forget to add a "use" statement for this annotation?"
I ilikely did but for my life I can't figure out where to add it. And I really would like to just use @Foo if possible.
Autoloading is apparently handled by AnnotationRegistry::registerAutoloadNamespace
which is a PSR-0 autoloader. Documentation/source.
I found that you can do a use My\Test\Foo
in the annotated file to use @Foo
as an annotation. And the reason for that is possible is because Doctrine re-parses the file solely for use
statements.
I stumbled accross this issue with error messages like:
Fatal error: Uncaught exception
Doctrine\Common\Annotations\AnnotationException' with message '[Semantical Error]
The annotation "@Symfony\Component\Validator\Constraints\NotNull" in property My\Namespace\Model\Foo\Bar::$name does not exist, or could not be auto-loaded.'
in var/www/virtual/hive/current/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php on line 54
while I was trying to get the symfony2 Validator component to work as a standalone in a legacy non-symfony2 project.
I was also under the impression that the annotations should already be autoloaded, whereas one indeed has to specifically realize that one has to use doctrine's autoloader in order to get the annotations working.
I have looked at how symfony2 loads the registry, and they do it like this in the app/autoload.php
<?php
use Doctrine\Common\Annotations\AnnotationRegistry;
use Composer\Autoload\ClassLoader;
/**
* @var ClassLoader $loader
*/
$loader = require __DIR__.'/../vendor/autoload.php';
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
return $loader;
My project uses a bootstrap.inc.php
file that always will be loaded and it had:
require_once PROJECT_PATH . '/vendor/autoload.php';
I just refactored it to look similar:
use Doctrine\Common\Annotations\AnnotationRegistry;
...
$loader = require_once PROJECT_PATH . '/vendor/autoload.php';
AnnotationRegistry::registerLoader([$loader, 'loadClass']);
And then the Annotation were found.