__wakeup()と__sleep()について
こんばんは。本を読みながらPHPの勉強をしている者です。
今オブジェクトの章をやっているんですが、オブジェクトのシリアライズの説明があったので、そこでシリアライズの説明が軽くあったのですが、いまひとつ理解できません。サンプルコードが載っていたのでまる写しし、コードが動かなかったので一部訂正して動くようにして、あらためて動作を確認しても何をしているのかよくわかりませんでした。
以下がそのサンプルコードです。
//Log.inc
<?php
class Log {
var $filename;
var $fp;
function Log($filename){
$this->filename=$filename;
$this->open();
}
function open(){
$this->fp=fopen($this->filename,"a") or die("{$this->filename}を開けません。");
}
function write($note){
fwrite($this->fp,"$note\n");
}
function read(){
return join('',file($this->filename));
}
function __wakeup(){
$this->open();
}
function __sleep(){
fclose($this->fp);
return array('filename');
}
}
?>
//front.php
<?php
include_once('Log.inc');
session_start();
extract($_SESSION);
?>
<html><head><title>フロントページ</title></head>
<body>
<?php
$now=strftime("%c");
if(!session_is_registered('l')){
$l=new Log("/tmp/persistent_log");
session_register('l');
$l->write("作成時刻 $now");
echo ("<p>セッションおよびログオブジェクトを作成しました。</p>");
}
$l->write("最初のページの読み込み時刻 $now");
echo "<p>ログの内容</p>";
echo nl2br($l->read());
?>
<a href="next.php">次のページへ</a>
</body>
</html>
//next.php
<?php
include_once('Log.inc');
session_start();
extract($_SESSION);
?>
<html><head><title>次のページ</title></head>
<body>
<?php
$now=strftime("%c");
$l->write("2ページ目の表示時刻 $now");
echo "<p>ログの内容</p>";
echo nl2br($l->read());
?>
</body>
</html>
このサンプルコードはたぶん、front.phpで宣言した$lが、セッション情報により保たれ、改めてnext.phpで$l=new Log(‘ファイルパス’)のように書かなくてもよい、ということを教えるためのものだと解釈しました。わからなかったのは__wakeup()メソッドと__sleep()メソッドのところなんですが、シリアライズするする直前と直後に呼び出すものだと本には書かれていましたが、呼び出し元もありませんし、勝手にタイミングを計って呼び出されるのなら、そのタイミングはどこでわかるのでしょうか?
function __wakeup(){
$this->open();
}
でいうと、$this->open();が__wakeup()メソッドを呼び出すタイミングなのでしょうか?これならなんとなくつじつまが合いますが…
また
function __sleep(){
fclose($this->fp);
return array('filename');
}
の、return array('filename')とはどこに対してプロパティの配列を返しているのでしょうか?本には「この関数の返り値は、バイトストリームに書き出す必要のあるメンバー名の配列です」と書いてありますが、「書き出す必要」は何を基準にしているのかもよくわかりません。
/tmp/persistent_logにバイトストリームを書き出すから、array('filename')になっているのですか?
また、persistent_logをテキストエディタで開いたら、内容は単なるログファイルの内容ですが、本には「永続オブジェクト$l」と書かれています。目に見えませんが、persistent_logの中にはオブジェクトも埋め込まれている(つまりただfopen()とfwrite()とfclose()の作業だけだと本当にただのログファイルですが、__wakeup()や__sleep()やセッションによってシリアライズされたオブジェクトの中にfopen()やfwrite()やfclose()を混ぜることによってログファイル兼オブジェクトになっていると)いう事ですか?
よくわからなくて自分なりに推測したことを書いたので、質問の意味がわかりづらいかもしれませんが、どなたか教えていただけませんか。
回答(1件)
- 最新から表示
- |
- 回答順に表示
- |
- ベストアンサーのみ表示
No.1ベストアンサー20pt
シリアライズとは、PHPの値を型などの情報も含めて、文字で表現することです。
たとえば、
echo serialize("abcdefg");
を実行すると、
s:7:"abcdefg";
となります。
s は文字列、7は長さ、そして内容になっています。
もっと、複雑な構造もシリアライズできます。
たとえば、
echo serialize(array(1, 2, array('abc', 'def')));
a:3:{i:0;i:1;i:1;i:2;i:2;a:2:{i:0;s:3:"abc";i:1;s:3:"def";}}
オブジェクトも、シリアライズできます。
アンシリアライズは、この文字表現から値を復元します。
で、セッションですが、セッション情報はシリアライズされて、サーバー側に保存されます。
セッションからの取出しには、アンシリアライズが行われます。
このときに __wakeup, __sleepが呼ばれます。
つまり、extractで、セッションから取り出されるときに、__wakeupが呼ばれ、ログファイルをオープンします。
__sleepは、オブジェクトの中で、シリアライズの対象としたいものだけを、配列で返します。複雑で、プロパティの多いオブジェクトの場合には、これは有効です。
ここでは、ファイル名だけをシリアライズするように設定していますね。
この回答へのお礼
返事が遅れましてすいません。ご丁寧な解説を頂いたにもかかわらずまだ完全には理解できませんが、それでも少し進歩できました。ありがとうございました。
- 最新から表示
- |
- 回答順に表示
- |
- ベストアンサーのみ表示











