2

Let's say you have a class which is compliant to the PSR logger interface standard, but you want it to be usable also by people who don't need logging or don't bother having a PSR logger. It's clear to me to use method injection for the logger(something like function setLogger(Psr\Log\LoggerInterface $logger){...}). Now I wonder how to call logger's methods if I can't be sure if a logger class was specified. One of the solutions would be to create a class that would act as a proxy to the logger, but I'm not sure that's the appropriate solution.

JanLikar
  • 1,296
  • 9
  • 22
  • You mean you want to avoid doing `if ($this->logger !== null)` everytime? Because testing if the logger is set is *a* solution. – Matthieu Napoli Sep 19 '13 at 07:51
  • The question is formulated weirdly, I'm sorry about that. And yes, that's precisely what I want to avoid. I want code to look as simple as possible, without checking if $this->logger is set every time there is something to be logged. – JanLikar Sep 19 '13 at 20:16

2 Answers2

3

You could implement a "NullLogger" and have it as default logger:

class NullLogger implement LoggerInterface
{
    public function error($message, $context = [])
    {
        // do nothing
    }
    // ...
}

class MyClass
{
    private $logger;

    public function __construct(LoggerInterface $logger = null)
    {
        $this->logger = $logger ?: new NullLogger();
    }

    public function doSomething()
    {
        $this->logger->info('');
        // ...
    }

    public function setLogger(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }
}

I would also seriously consider the good old:

if ($this->logger) {
    $this->logger->...
}

(if it's not used everywhere) since it's more lightweight.

But the first solution is definitely valid IMO.

Finally, you can also decide that logging has nothing to do directly with your class, and that's behavior that could be left to the responsiblity of the user. You can provide extension points using Events, or the Template Method Pattern (see my question about that if you are interested: Should I use events or the "template method" pattern for an open source library?).

To sum up, I'd say it depends on the use case: do you log a lot? is "logging" part of the functionality you provide? or is it cleary a separate concern?

Community
  • 1
  • 1
Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
1

As it turns out, PSR standard defines a null logger, that can be used for this purpose.

<?php
use \PSR\Log\NullLogger
JanLikar
  • 1,296
  • 9
  • 22