Annotations

On top of autowiring and PHP configuration files, you can define injections using annotations.

Installation

Annotations are disabled by default. To be able to use them, you first need to install the Doctrine Annotations library using Composer:

composer require doctrine/annotations

Then you need to configure the ContainerBuilder to use them:

$containerBuilder->useAnnotations(true);

Annotations are written in PHP docblock comments. They are used by a lot of modern libraries and frameworks, like Doctrine, Symfony, PHPUnit

@Inject

@Inject lets you define where PHP-DI should inject something, and what it should inject. You can optionally combine it with @var and @param phpdoc tags to define what should be injected.

It can be used on:

Here is an example of all possible uses of the @Inject annotation:

class Example
{
    /**
     * Annotation combined with phpdoc:
     *
     * @Inject
     * @var Foo
     */
    private $property1;

    /**
     * Explicit definition of the entry to inject:
     *
     * @Inject("db.host")
     */
    private $property2;

    /**
     * Annotation combined with phpdoc:
     *
     * @Inject
     * @param Foo $param1
     * @param Bar $param2
     */
    public function __construct($param1, $param2)
    {
    }

    /**
     * Annotation combined with the type-hint:
     *
     * @Inject
     */
    public function method1(Foo $param)
    {
    }

    /**
     * Explicit definition of the entries to inject:
     *
     * @Inject({"db.host", "db.name"})
     */
    public function method2($param1, $param2)
    {
    }

    /**
     * Explicit definition of parameters by their name:
     *
     * @Inject({"param2" = "db.host"})
     */
    public function method3(Foo $param1, $param2)
    {
    }
}

Note: importing annotations with use DI\Annotation\Inject; is optional.

Troubleshooting @Inject

Injectable

The @Injectable annotation lets you set options on injectable classes:

/**
 * @Injectable(scope="prototype", lazy=true)
 */
class Example
{
}

The @Injectable annotation is optional: by default, all classes are injectable.

Limitations

There are things that can't be defined with annotations:

For that, you can combine annotations with definitions in PHP.

Troubleshooting

Since annotations are in PHP docblocks, the opcache option opcache.load_comments must be set to 1. If it is set to 0, comments will be stripped from the source code and annotations will not work.

The default value for this option is 1 so everything should work by default. There is also no reason to set this option to 0 as it brings no performance benefit.

To check the value of this option, you can run the following command:

$ php -i | grep "opcache.load_comments"

Furthermore, please mind that annotations are case-sensitive. You should write @Inject and @Injectable instead of @inject and @injectable to avoid bugs on certain systems.