Phalcon\LoggerをPSR-3として扱う

Phalcon\Logger は Phalcon 1.3 から [PSR-3 Logger Interface](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) に対応しています。

ですが、初期設定ではこれが有効になっていません。

追記：Phalcon2の場合はこちらを参照ください。

* [Phalcon2のLoggerがPSR-3インタフェースを実装してくれない件への対応](http://qiita.com/k-holy/items/04146041a4e14445402b)


## PHP の設定で phalcon.register_psr3_classes を有効にする

php.iniで以下のディレクティブを指定し、 Phalcon フレームワークで PSR-3 を有効にします。

```ini
[Phalcon]
; Enable PSR-3 classes and interfaces @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
phalcon.register_psr3_classes = On;
```

## PSR-3 の何が嬉しいのか

以下は 単に ``opcache_get_status()`` 関数の結果を返したり、リセットするだけのしょうもないクラスですが、``\Psr\Log\LoggerAwareInterface`` を実装するとともに、コンストラクタの配列引数に ``logger`` というキーで ``\Psr\Log\LoggerInterface`` を実装したオブジェクトを与えられることを前提としています。

```php
namespace Acme\Domain\Service;

/**
 * OPcacheサービス
 *
 * @author k.holy74@gmail.com
 */
class OPcacheService implements \Psr\Log\LoggerAwareInterface
{

    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;

    /**
     * オブジェクトを初期化します。
     *
     * @param array | ArrayAccess パラメータ配列
     */
    public function __construct($parameters = array())
    {
        if (!extension_loaded('Zend OPcache')) {
            throw new \RuntimeException('Required extension "Zend OPcache" is not loaded.');
        }
        if (!isset($parameters['logger'])) {
            throw new \InvalidArgumentException('Required parameter "logger" is not appointed.');
        }
        $this->setLogger($parameters['logger']);
    }

    /**
     * ロガーをセットします。
     *
     * @param Psr\Log\LoggerInterface
     */
    public function setLogger(\Psr\Log\LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    /**
     * OPcache ステータスの配列を返します。
     *
     * @return array
     */
    public function getStatus()
    {
        $opcache_status = opcache_get_status();

        if (isset($opcache_status['scripts'])) {
            ksort($opcache_status['scripts']);
        }

        if (isset($opcache_status['memory_usage'])) {
            $this->logger->debug(implode(', ',
                array_map(
                    function($key, $value) {
                        return sprintf('%s:%s', $key, $value);
                    },
                    array_keys($opcache_status['memory_usage']),
                    array_values($opcache_status['memory_usage'])
                )
            ));
        }

        return $opcache_status;
    }

    /**
     * OPcacheをクリアします。
     *
     * @return boolean
     */
    public function reset()
    {
        return opcache_reset();
    }

}
```

このクラスは PSR-3 には依存していますが、Phalcon フレームワークには依存していません。

Phalcon の PSR-3 を有効にすることでそのまま利用できますが、たとえば Phalcon ではなく Silex を採用した別のプロジェクトでこのクラスを使う場合、同じく ``\Psr\Log\LoggerInterface`` が実装された Monolog を使っても問題ないわけです。

デバッグを含めたロギング処理はあらゆるレイヤで必要とされるものですが、このような共通インタフェースは、アプリケーションフレームワークの開発者だけでなく、利用者としてもメリットがあるという例でした。

なお [PHP-FIG(PHP Framework Interoperability Group)](http://www.php-fig.org) では他にも [HTTP message Interface](https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md) や [Cache Interface](https://github.com/php-fig/fig-standards/blob/master/proposed/cache.md) といったフレームワーク共通のインタフェースが検討されています。