PHP でデザインパターン (シングルトン)
PHP デザインパターン
Published: 2018-03-11

Singleton の目的

  • 指定したクラスのインスタンスが絶対に1個しか存在しないことを保証したい
  • インスタンスが1個しか存在しないことをプログラム上で表現したい

また、

たとえば、システムの設定を表現するクラスや、システム全体で一度読み込んだデータをキャッシュしておくクラスで利用する。

Singleton の実装に関して

  • Singleton クラスのコンストラクタは private にする。

  • Singleton クラス外からコンストラクタを呼ぶことを防ぐため。

  • 下記の方法でインスタンス生成できないようにする

    • 自身を外部から new する
    • 外部から clone する
    • 派生クラスを new する(派生クラスを作ることができないようにする)

Singleton の実装例

<?php
// final で派生クラスを作ることができないようにする
final class Singleton
{
    private static $instance;
    private $id;

    private function __construct()
    {
        $this->id = time();
    }

    private function __clone()
    {
    }

    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    public function getId()
    {
        return $this->id;
    }
}

$ins1 = Singleton::getInstance();
sleep(3);
$ins2 = Singleton::getInstance();

print($ins1 === $ins2);
print "\n";
print($ins1->getId() === $ins1->getId());
print "\n";

出力結果

1
1

エラーパターンの確認

  • 自身を外部から new する
$ins0 = new Singleton();

// Fatal error: Call to private Singleton::__construct() が発生
  • 外部から clone する
$clone_class = clone $ins1;

// Fatal error: Call to private Singleton::__clone() が発生
  • 派生クラスを new する(派生クラスを作ることができないようにする)
class ChildSingleton extends Singleton
{
    public function __construct()
    {
    }
}
$ins3 = new ChildSingleton();

// Fatal error: Class ChildSingleton may not inherit from final class (Singleton) が発生

参考