Conditionally check suggested package existence in PHP (Composer)

670 views Asked by At

I'm developing a PHP package (distributed on Composer) that could benefit from logging, but doesn't require it. I've seen many sample composer.json files that include suggested packages like so:

{
    "suggest": {
        "monolog/monolog": "Allows more advanced logging of the application flow"
    }
}

How would I go about detecting if the library is available at runtime? I want to instantiate a default instance of the \Monolog\Logger if it is available, allow the consumer of the package to pass in their own Psr\Log\LoggerInterface interface implementation if they desire. Are there any best practices around this?

3

There are 3 answers

0
Sven On

If you suggest using a logger, it is up to the developer using your package to make use of that!

I'd suggest you depend on the PSR-3 logger package to allow for easy integration, and let the developer do the rest. No magically using a logger that you think is installed! That Psr\Log\LoggerAwareInterface is there for a reason.

0
Tomas Votruba On

I would advise to create custom package that would include all monolog-related logic. If someone would like to use it, he can include it and it works.

Optional dependency is code smell and magic, that is easy to hide. For deeper explanation, checkout There no such thing as optional dependency article.

0
Seldaek On

I tend to agree with Tomáš Votruba's answer in terms of best practice, but I will answer the original question anyway:

If you really want to detect if monolog is present and do some magic if it is, and this applies to any package really, the easiest is to call class_exists('Monolog\Logger') and if it's true you know monolog is there. This should work so long as you don't have a broken autoloader in the chain that throws an exception when it can't find a class, but if you only use Composer's autoloader it is all good.

For sure it is a good idea to let the user inject their own PSR-3 implementation however and to use it if it's there.