2

I'm trying to do something new with virtual types. I understand that you can create these in your di.xml and use them as arguments for other types in di.xml. But can I also declare a virtual type and use it in a constructor in a PHP class?

For example: I'm trying to do something like this:

<virtualType name="Vendor\Module\Logger\Handler"
             type="Magento\Framework\Logger\Handler\Base">
    <arguments>
        <argument name="filePath" xsi:type="string">/var/log/custom.log</argument>
    </arguments>
</virtualType>

And:

public function __construct(
    \Vendor\Module\Logger\Handler $logger
) {
    $this->logger = $logger;
}

But this does not work. I also tried:

<preference for="Vendor\Module\Logger\Handler" type="custom_logger"/>
<virtualType name="custom_logger"
             type="Magento\Framework\Logger\Handler\Base">
    <arguments>
        <argument name="filePath" xsi:type="string">/var/log/custom.log</argument>
    </arguments>
</virtualType>

With the same PHP code, but the results are the same. I get a ReflectionException that class Vendor\Module\Logger\Handler does not exist.

I find this odd, because the way I always understood, the Object Manager uses reflection to see what classes are required in the constructur, and uses the di.xml configuration on it's turn to bring this back to a class. So why isn't this working with a virtual type?

5

What you're trying won't work because php must be able to find the class that you are giving in a constructor argument's type hint. This is part of the language and can't be overriden. Php is unaware of di.xml settings.

The object that Object Manager passes to a constructor must implement or inherit from the given type hint. In the case of virtual types, object manager creates an instance of the underlying class with the given configuration and passes this into a constructor.

The class receiving the virtual type as an argument must use the underlying class (or an ancestor/interface) for the argument's type hint. This must be a concrete class/interface that php understands. Hence, The virtual type itself does not actually exist, it's just a shortcut for use in configuration xml only.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.