複数の機能をひとつのクラスにまとめて、そのクラスをスクリプト内で何度も呼び出すケースでは、毎回 new でインスタンスを生成すると、メモリ消費が大きくなったり、コンストラクタが何度も実行されたりと、パフォーマンスへの影響が気になることがあります。
こういった場合に有効なのが「シングルトンパターン」です。クラスのインスタンスを1つだけ生成し、それを再利用する設計です。
■ シングルトンの実装例
以下は、シンプルなシングルトン実装の例です。
<?php
class MySingleton
{
private static ?MySingleton $instance = null;
// 外部からインスタンス生成を禁止
private function __construct() {}
// インスタンス取得(初回のみ実行)
public static function getInstance(): MySingleton
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
// 任意のメソッド
public function doSomething(): void
{
echo "シングルトンメソッド実行中\n";
}
}
■ 使用例
シングルトンを利用する場合は、getInstance() を通じてインスタンスを取得します。
$singleton = MySingleton::getInstance();
$singleton->doSomething();
この実装では、getInstance() を呼び出すことで、初回のみ new によってインスタンスが生成され、2回目以降は既存のインスタンスが再利用されます。
※private static ?MySingleton $instance = null; の「?」はPHP 7.1以降の型宣言で、nullを許容しています。
シングルトンは、その性質上「毎回インスタンスを新規生成するわけではない」ため、インスタンスの内部状態が呼び出し元によって影響を受ける可能性があります。
たとえば、クラス内部に状態(プロパティなど)を保持し、呼び出すたびにその状態に依存して処理を行うようなスクリプトでは、以前の状態が次の処理に影響を与えてしまうことがあります。
このように、「毎回 new されない」というシングルトンの挙動は、場合によっては意図しない副作用を引き起こす原因となるため、設計段階で十分に注意が必要です。
また、用途によってはスレッドセーフではない実装が問題になることもあります。特にCLIや並列処理環境でシングルトンを使用する場合は、ロックや排他制御が必要になるケースもあるため、実行環境や要件に応じて慎重に選択する必要があります。