I'm looking forward to having traits in PHP 5.4 :)

One of the 'traits' I find myself constantly adding to library files is optional logging of it's behaviour. The library class has it's own log method, that checks to see if the instance has had a logger injected and if so, logs the message. I see this as a perfect candidate for becoming a reusable trait, as I tend to have the same code copy/pasted throughout my library classes.

The problem is, according to the rfc, traits aren't supposed to have state/properties, which makes it difficult to have a DI setter method in a trait. I guess it provides further protection against clashes, but you could always make the property name very unique, though I suppose that not a particularly good practice. However, setting properties in the traits seems to work just fine, so here's a quick demo of adding logging capabilities to a class via traits in PHP 5.4. Needless to say, because this may be undesired behaviour and it's only an alpha release, I'm not banking on this working in the future.

<?php

/**
 * Logging trait
 */
trait Logging
{
    /**
     * @var Zend_Log
     */
    protected $_logger = null;

    /**
     * Set logger
     *
     * @param Zend_Log $logger
     * @return void
     */
    public function setLogger(Zend_Log $logger) 
    {
        $this->_logger = $logger;
    }

    /**
     * Log something
     *
     * @param string $level
     * @param string $msg
     * @return void
     */
    protected function log($level, $msg)
    {
        if ($this->_logger !== null) {
            $this->_logger->{$level}($msg);
        }
    }

}

/**
 * Hello World
 */
class HelloWorld
{
    use Logging;

    /**
     * Run the hello world
     */
    public function run()
    {
        $this->log("info", "running");
        echo "Hello World!\n";
        $this->log("info", "done");
    }
}

/**
 * Traits demo
 */
date_default_timezone_set('Europe/London');
require_once 'Zend/Log.php';

$logger = Zend_Log::factory(array(
    array(
        'writerName'   => 'Stream',
        'writerParams' => array(
            'stream'   => 'php://stdout',
        ),
    ),
));

$hw = new HelloWorld;
$hw->setLogger($logger);
$hw->run();

After downloading and compiling the latest alpha, I can run the code seeing the logging I wanted.

davem@marajade:~$ cd src
davem@marajade:src$ tar -zxvf ~/Downloads/php-5.4.0alpha3.tar.gz
davem@marajade:src$ cd php-5.4.0alpha3
davem@marajade:php-5.4.0alpha3$ ./configure --disable-all
davem@marajade:php-5.4.0alpha3$ make
davem@marajade:php-5.4.0alpha3$ cd ~/src/traits-demo
davem@marajade:traits-demo$ ~/src/php-5.4.0alpha3/sapi/cli/php run.php 
2011-08-05T23:33:15+01:00 INFO (6): running
Hello World!
2011-08-05T23:33:15+01:00 INFO (6): done
davem@marajade:traits-demo$