ページを移動しても、
変数や配列等を保持できる仕組みを作りたい。
serialize/unserialize関数を使うと簡単にできるらしい。
○serialize関数
上記サイトのソースをそのまま。
<?php $a = new A; echo serialize($a); class A{ var $hash; function A() { $this->hash = array( "a"=>"b", "c"=>"d", "e"=>"f" ); } } ?>
で、実行すると結果は、
O:1:"a":1:{s:4:"hash";a:3:{s:1:"a";s:1:"b";s:1:"c";s:1:"d";s:1:"e";s:1:"f";}}
という文字列が出力される。
この文字列の構造は、
O:(クラス名の文字数):"(クラス名)":(プロパティの個数):{(プロパティの内容)}
ってなってるみたいです。
(プロパティの内容)は、
s:(プロパティ名の文字数):(プロパティ名);(型)[:(文字数/配列の要素数)]:(値);.... (型:s=string, a=array, d=double....)
という感じになってて、
配列の場合は(値)の部分が、
{(キー);(値);(キー);(値)....}
と並んでますね。
試しに、ソースを以下のように書き換えてあげると、
<?php $a = new test; echo serialize($a); class test{ var $aaa; var $hashed; function __construct() { $this->aaa = 2.4; $this->hashed = array( "america"=>"boston", "china"=>"denmark", "england"=>"france" ); } }
出力結果は以下のようになります。
O:4:"test":2:{s:3:"aaa";d:2.4;s:6:"hashed";a:3:{s:7:"america";s:6:"boston";s:5:"china";s:7:"denmark";s:7:"england";s:6:"france";}}
○unserialize関数
http://php.net/manual/ja/function.unserialize.php
serialize関数で作った文字列を、
元のオブジェクトに戻す関数。
上記ソースのはじめの部分を、
以下のように書き換える。
$a = new test; print('a : '); print_r($a->hashed); print("<br />\n"); $ser_a = serialize($a); $b = unserialize($ser_a); print('b : '); print_r($b->hashed); (クラス部分はそのまま)
出力結果は、
a : Array ( [america] => boston [china] => denmark [england] => france ) b : Array ( [america] => boston [china] => denmark [england] => france )
serialize/unserialize関数で、
“$a”と同じ内容のオブジェクト、
“$b”ができたことを確認できました。
●使ってみる
これらを使って、ページを移動しても、
オブジェクトのプロパティを保持できる仕組みを作る。
“serialize.php”を開いた時に、
オブジェクトをserializeして一時ファイルに保存。
(一時ファイルの保存先として”tmp”ディレクトリを作成のこと)
ボタンを押すと”unserialize.php”に飛んで、
保存したものを読み出して、
unserializeしてプロパティを表示。
読み出し後は一時ファイルを削除。
=== serialize.php =============== <?php /*クラス部分を別ファイルにしてrequire*/ require_once 'test.php'; /*オブジェクトの立ち上げとシリアライズ*/ $a = new test; $ser_a = serialize($a); /*一時ファイル名を指定*/ $now = new DateTime(); $file_name = 'tmp/test_'.$now->format('ymd-his').'.txt'; /*一時ファイルへ書き込み*/ $file = @fopen($file_name, x) or die('書き込みエラー'); flock($file, LOCK_EX); fwrite($file, $ser_a); flock($file, LOCK_UN); fclose($file); print_r ($a->hashed); print ("<br />\nオブジェクトを".$file_name.'に保存しました。'); ?> <!-- unserialize.phpへのリンク : formでファイル名渡す --> <form method="POST" action="unserialize.php"> <input type="submit" value="unserializeへ"> <input type="hidden" name="file_name" value="<?=$file_name ?>"> </form> === unserialize.php =============== <?php require_once 'test.php'; if (empty($_POST['file_name'])) die('ファイル名が指定されていません!'); $file_name = $_POST['file_name']; /*ファイル名チェック(一時ファイル以外を削除しないための保険) "tmp/test_"で始まる文字列以外は認めない*/ if ( preg_match('|^tmp/test_|', $file_name) == 0 ) die('ファイル名が正しくありません!'); /*一時ファイルから読み込み*/ $file = @fopen($file_name, r) or die('読み込みエラー'); flock($file, LOCK_SH); $ser_b = fgets($file, 1024); flock($file, LOCK_UN); fclose($file); unlink($file_name); // 読み込み後、一時ファイルを削除 /*unserializeして出力*/ $b = unserialize($ser_b); print_r($b->hashed); ?> <br /> <input type="button" onclick="location.href='serialize.php'" value="戻る"> === test.php =============== (上記プログラムのクラス部分そのまま)