Singleton

色々調べてみたら、偶然にいいもの見つけた。

こんな質問を見つけた。
環境は linux(RedHatES3)、PHP5+apache1.3 です。

PHP5 から本格的なオブジェクト指向プログラムが可能となりましたが、PHP5 をapache のモジュール版として使っている場合、オブジェクトの消滅タイミングは何時になるのでしょうか?JAVA ですと、GC により使われなくなったオブジェクトをクリアしますが、PHP5 のGC も同様の動きをするのでしょうか?

また、apache のモジュール版としてPHP5 を利用しているので、PHP5 のメモリ空間は = apache のプロセスとなると思っています。そう考えると、オブジェクトの削除タイミングはGC 制御ではなく、普通にプロセスが死んだときのような気もしますがいかがでしょうか?逆に、そうであれば、オブジェクトをstatic にする意味も薄れてくるのかな?

(略)

すいません、多分質問の仕方が悪かったのかと思います。

プログラム的なstatic に意味があるのか?ということではなく、例えば、JAVA でsingleton などを実装した場合を考えます。JAVA では、VM 上にオブジェクトが一度だけロードさて、他スレッドでシェアされます。しかし、PHP5 でsingleton を書いた場合、プロセス単位でオブジェクトが管理されていると思ってますので、スレッドでない以上、プロセス間でオブジェクトをシェアできないので、singleton の意味はあるのか?という質問でした^^

そう考えると、JAVA のように効率的な構造をしてないので、PHP5 でオブジェクト指向プログラムをする意味というのは、あくまでも再利用性のみを追求する場合かな?っと思っているのです。。

—–

PHP の変数 (zval) はリファレンスカウンティングで管理されており、不要になった変数は型を問わず、参照カウンタが 0 になった時点で削除されます。
参照カウンタがデクリメントされるのは主に変数が unset されたとき、別の値が代入されたとき、定義されたスコープを抜けたとき等です。
また、リクエストが終了した時点 (CLI ではプロセスが終了した時点) で変数が登録されているシンボルテーブルが破棄され、その際にすべての変数は再帰的に開放されます。
マルチスレッド対応の SAPI (公式の Windows 版 Apache2Handler, IIS 等) でもシンボルテーブルはスレッドごとに管理されており、他のスレッドの状態を気にかける必要はありませんし、逆に他のスレッドの変数を参照することもできません。

このため PHP で書いたプログラムは、どの Web サーバ上でも SAPI を気にすることなく同じように動くことが期待できます。

というわけで、PHP では言語仕様として Java の様なオブジェクトの永続化はありません。
が、APC のような共有メモリや MMAP にオブジェクトを保存する機能を備えた拡張モジュールを使えば似たようなことは可能です。

「Singleton の意味はあるのか?」ということですが、PHP の場合はインスタンス生成コストを抑えたい場合、スコープをまたいで (PHP のスコープは非常に大雑把で、グローバル or 関数ローカル のみです) コンフィギュレーションやコンテキストを共有したい場合に用いられることが多いと思います。

http://www.phppro.jp/qa/570
——-

へー。

Singletonってなに?^^

http://ja.wikipedia.org/wiki/Singleton_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

へー。

——-
<%nobr%>


<%estag%>
class Singleton {
private static $singleton;
private $_name;
private function __construct() {
print "create instance
";
}
public static function getInstance() {
if (!is_object(Singleton::$singleton)) {
Singleton::$singleton = new Singleton();
}
return Singleton::$singleton;
}
public function setName($name) {
$this->_name = $name;
}
public function getName() {
return $this->_name;
}
}

print ‘Singleton.php test start.
’;

$object1 = Singleton::getInstance();
$object2 = Singleton::getInstance();

$object1->setName(‘akira’);
print $object1->getName() . ‘
’;
print $object2->getName() . ‘
’;
$object2->setName(‘yoshiko’);
print $object1->getName() . ‘
’;
print $object2->getName() . ‘
’;

$object3 = new Singleton();
print $object3->getName() . ‘
’;

echo ‘Singleton.php test end.
’;
?>
<%/estag%>

<%/nobr%>

これで、$objcet1も$object2も同じインスタンスです。
$object3は生成出来ません。

で、以下結果。
———–
Singleton.php test start
create instance
akira
akira
yoshiko
yoshiko

Fatal error: Call to private Singleton::__construct() from context ” in /var/www/public_html/exsample/Singleton.php on line 34
———–

34行目でprivateになってるコンストラクタを呼び出そうとしているので、エラー(Fatal error)が発生しています。
そのため、「Singleton.php test end.」までは進みません。

…だって。
メモしておく。

なるほどー。
今度使ってみよう。