DevilishSkull
DevilishSkull

Reputation: 67

How to autoload custom annotation classes without using AnnotationRegistry?

I'm using Doctrine Annotations library (not the whole Doctrine, only annotations) and want to make a custom annotation class.

composer.json:

{
  "require": {
    "doctrine/annotations": "^1.6"
  },
  "autoload": {
    "psr-4": {
      "annotations\\": "annotations",
      "entities\\": "entities"
    }
  }
}

index.php:

<?php

require 'vendor/autoload.php';

use Doctrine\Common\Annotations\AnnotationReader;

$annotationReader = new AnnotationReader();
$reflectionClass = new ReflectionClass(entities\MyClass::class);
$classAnnotations = $annotationReader->getClassAnnotations($reflectionClass);
var_dump($classAnnotations);

entities/MyClass.php

<?php

namespace entities;

use annotations\TestAnnotation;

/**
 * @TestAnnotation("123")
 */
class MyClass
{

}

annotations/TestAnnotation.php

<?php

namespace annotations;

/**
 * @Annotation
 * @Target("CLASS")
 */
final class TestAnnotation
{
    /**
     * @var string
     */
    public $value;
}

It gives me the following error:

[Semantical Error] The annotation "@annotations\TestAnnotation" in class entities\MyClass does not exist, or could not be auto-loaded.

The only solution i found on the Internet is to use AnnotationRegistry::registerLoader or something similar, but it is deprecated so i'd like to solve the problem in another way.

Upvotes: 2

Views: 1080

Answers (2)

Noman
Noman

Reputation: 31

I posted a similar question and answered it myself as apparently the answer to it turned out to be far more obscure than I could have imagined, ultimately taking a whole day to track down, though easy enough to fix:

composer require “yogarine/doctrine-annotation-autoload”
composer dump-autoload

See https://stackoverflow.com/a/59966965/4538469 for details.

Upvotes: 0

malarzm
malarzm

Reputation: 2966

One way to work around registering a loader is explicit require_once of all files with custom annotations somewhere during application's bootstrap (such approach was used in the MongoDB ODM but was dropped).

In the next major version annotations will rely on autoloading so no code will be required for the setup. To have a future-proof code you could use:

use Doctrine\Common\Annotations\AnnotationRegistry;

if (class_exists(AnnotationRegistry::class)) {
    AnnotationRegistry::registerLoader('class_exists');
}

You could explicitly pass Composer's autoloader but class_exists will work just fine given Composer's autoloader is already in use.

Upvotes: 4

Related Questions