Writing a static Log class for PHP I wanted to write a simple Log class for PHP, I use ajax calls with AngularJS and often return the log in an array

Example:

$return['data'] = $returnedDataArray;
$return['log'] = $logDataArray;
$return['status'] = 'success';
echo json_encode($return);


I was hoping to implement a logging system in my other classes, like my DB wrapper, etc.

Example:

Log::put('sql', $sql, 'DB');
Log::put('fields', $fieldsArray, 'DB');


And than pass the log.

Example:

$return['log'] = Log::getLog();


Here is my Log class:

class Log {
    private static $_loggingOn = true, $_log = array();

    public static function put ($key, $value, $className = null, $functionName = null) {
        if ($className) {
            if ($functionName) {
                self::$_log[$className][$functionName][$key] = $value;
            } else {
                self::$_log[$className][$key] = $value;
            }
        } else {
            self::$_log[$key] = $value;
        }
    }

    public static function getLog () {
        if (self::loggingOn()) {
            return self::$_log;
        }
        return array('Logging is turned off.');
    }

    public static function loggingOn () {
        return self::$_loggingOn;
    }
}


I am wondering if using the static class would be a recommended approach?
No, using static methods is not a recommand approach. With static methods, your class always knows which class it calls. That means you can never switch to another logger class (e.g. one that writes the logs in a file).

A class should be independent of other classes as much as possible. In this case, you should just create a LoggerInterface (or use the one from PSR-3) and base on that interface. Inject it in the classes that needs a logger and then use that object. This way, you can always change from loggers (as long as they implement the correct interface) and your class doesn't know which classes it uses.

Example:

interface LoggerInterface
{
    public function put($key, $value, $class = null, $function = null);
    public function getMessages();
}

class Logger
{
    protected $messages;

    public function put($key, $value, $class = null, $function = null)
    {
        // ...
    }

    public function getMessages()
    {
        // ...
    }
}

class DataBase
{
    protected $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this-&gt;logger = $logger;
    }

    public function someDbFunction(...)
    {
        // ... do something

        $this-&gt;logger-&gt;put(...); // log something
    }
}


This approach is called Dependency Injection. To make live easier for you, you can sue a Dependency Injection Container (also called a Service Container) to manage which classes depends on which other classes and creating those objects. A simple example is Pimple



There are also more disadvantages of using static methods. You can for instance never have 2 different instances of the logger, as there are no instances. That means that all messages are put in the same instance. You may want to internally use a logger in the Database section of your lib and another logger in the Form section of your lib and then one logger for your complete lib.