2月 172014
 

こんばんは。ファガイです。

本日はPHP5.4におけるシングルトンパターンの実装に関して書きたいと思います。

これを書こうと思ったのは自分がシングルトンパターンについて調べてた時に、「何かこの実装微妙だよね」とか、思った結果です。
最近書かれるブログでも、ちょっと書かれてる内容が古いな・・・って。ってことで書いてます。

PHP5.4以前のシングルトンパータンの実装に関しては、
絶版になったPHPによるデザインパターン入門のページを閲覧すると良いかと思います。
PHPによるデザインパターン入門

実を言うと、先日書きました、
ReflectionClassについて調べる – 新人Webエンジニアの記録。
が結構参考になりました。

PHP5.4におけるSingleton Pattern

こんな感じです。traitと、Reflection、遅延静的束縛を必要とします。

trait TraitSingleton
{
    /**
     * get instance.
     */
    public static function getInstance() {
        static $instance; // 静的なinstanceを保持するための変数

        // インスタンスが存在しない時だけインスタンスを作る
        if(! $instance)
        {
            // 遅延静的束縛
            $reflection = new ReflectionClass(get_called_class());
            $construct = $reflection->getConstructor();
            $construct->setAccessible(true);

            // インスタンスをコンストラクタ無しで作成
            $instance = $reflection->newInstanceWithoutConstructor();

            // コンストラクタを実行する
            $construct->invokeArgs($instance ,func_get_args());
        }

        return $instance;
    }

    /**
     * the instance clone is not allowd
     * @throws RuntimeException
     */
    public final function __clone()
    {
        throw new RuntimeException('Clone is not allowed against ' . get_called_class($this));
    }
}

ちょっとした解説

あんまり必要ないかもですが・・・。
基本的にこのトレイトは以下のような使い方をします。

class Sample
{
    use TraitSingleton;

    private function __construct()
    {
        // コンストラクタ
    }
}

$obj = Sample::getInstance();

はい。こんな感じ。

インスタンスをコンストラクタ無しで作る理由は、単にコンストラクタが実行出来ないためです。
privateなので。

コンストラクタだけをsetAccessibleでアクセス可能にして実行させることで、可能としています。

なお、フレームワーク等での実装だと一つ上にクラス等を被せてるので、publicでコンストラクタを書いてもシングルトンになってますね。

ではでは。

Pocket

 Posted by at 8:57 PM

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*