こんばんは。松田です。
明日弊社にてPieceFramework勉強会が開かれるということで、その前にPieceFramework開発に役立つネタをひとつ
Piece Frameworkとは・・・
Piece FrameworkはPHP4/PHP5に対応したWebアプリケーションフレームワークです。Piece FrameworkはステートフルでセキュアなWebアプリケーションフレームワークPiece_Unity, Piece_Unityの基盤となっているWebフローエンジンと継続サーバを提供するPiece_Flow, バリデーションフレームワークPiece_Right, その他関連プロダクトから構成されています。
というものです。(Piece Framework公式サイトより)
このPiece Frameworkを使ってアプリケーションを実装する機会があったのですが、その開発中にしょっちゅう悩まされる問題がありました。
それが「セッション残ってるよ問題」です。
Piece Frameworkはフローの初期から終了時までのデータをセッションに保存しておきます。そのため、アプリケーションの実行途中でフローの流れを変えるようなスクリプトを作成すると、すぐにエラーが出てしまうのです。これは新しく機能を追加した場合などにも当てはまります。新機能を付けるたびにエラーが出ちゃうのです。
最初のうちは新機能をつけるたびに /webapp/sessions/内のsess_* ファイルをコマンドで削除していたのですが、だんだん面倒になってきたので今回のモノを作成しました。
で、前置きが長くなりましたが、今回作成するのは、このPieceFrameworkのセッションを消してくれるブックマークレットです。開いているページに関係なく特定のスクリプトが実行できるブックマークレットは、こういった処理とものすごく相性がいいのです。
以前ブックマークレットの作り方をちらっと紹介しましたが、今回もブックマークレットを作成するので、興味のある方は先にこちらも見ておくといいかもしれません。
http://www.asial.co.jp/blog/176
まずはセッションを削除するPHPスクリプトを作成します。
詳しい説明なしで一気に全部書いちゃいますが、下のようなスクリプトになります。
echo文でalert()を出力していますが、その理由は後ほど。。
deletesession.php
<?php
// 各ディレクトリの指定
$dir = dirname(__FILE__);
$webapp_dir = $dir . "/../webapp/";
// セッションが格納されているディレクトリ
$sessions_dir = $webapp_dir . "sessions/";
// 削除するファイルの一覧を取得
$delete_list = glob($sessions_dir . "sess_*");
// 削除するファイルがなければ終了
if (!count($delete_list)) {
echo "alert('no files...');";
exit;
}
// ファイルを削除
$success_list = array();
$failure_list = array();
foreach ($delete_list as $file_name) {
$ret = unlink($file_name);
if ($ret) {
$success_list[] = $file_name;
} else {
$failure_list[] = $file_name;
}
}
// 削除結果の文字列を生成
$result_str = "";
if (count($success_list)) {
// 削除成功したファイル
$result_str .= "Delete Success!\n";
$result_str .= join("\n", $success_list) . "\n";
}
if (count($failure_list)) {
// 削除失敗したファイル
$result_str .= "Delete Failure!\n";
$result_str .= join("\n", $success_list);
}
// JavaScriptに文字列を送るため、\nを\\nに変換
$result_str = str_replace("\n", "\\n", $result_str);
// 削除結果をalertで表示
ob_end_clean();
echo "alert('{$result_str}');";
exit;
?>
これをブラウザでアクセス可能なディレクトリに設置しておきます。
ここではこのURLをhttp://www.example.com/deletesession.phpとしておきます。
次にこのスクリプトをブックマークレットから実行させます。
これをブックマークレットから実行させるには、「src="http://www.example.com/deletesession.php"」 属性を持ったscriptタグを生成し、document.bodyにappendChild()します。
つまり、
<script type="text/javascript" src="http://www.example.com/deletesession.php"></script>
を作り出して即時実行させるわけです。
PHPスクリプト内のechoでalert()を出力していたのはこのscriptタグでalert文を実行させるためです。
これでセッション削除スクリプトを実行させることができるようになります。
このブックマークレットのスクリプトは以下のようになります。
javascript:(
function() {
var el=document.createElement('script');
el.type='text/javascript';
el.src='http://www.example.com/deletesession.php?i='+(new Date().getTime());
document.body.appendChild(el);
document.body.removeChild(el);
}
)();
appendChild()直後にremoveChild()を行ったのは余計なscriptタグをいつまでもHTML内に残しておかないためです。
ですが、ここでremoveChild()を行うとFirefox以外のブラウザではスクリプト自体が動かなくなってしまったので、IEやOperaで使用する場合は削除してしまいましょう。
そしてこれをいつものように一行にまとめて完成です。
Firefox版
javascript:(function() {var el=document.createElement('script');el.type='text/javascript';el.src='http://www.example.com/deletesession.php?i='+(new Date().getTime());document.body.appendChild(el);})();
ただし、IEとOperaで使用する場合、最後のdocument.body.appendChild(el);があるとうまく動かないようなので削除してしまいます。
IE/Opera版
javascript:(function() {var el=document.createElement('script');el.type='text/javascript';el.src='http://www.example.com/deletesession.php?i='+(new Date().getTime());document.body.appendChild(el);})();
これをリンクバーのブックマークに登録しておき、いつでもクリックできるように準備しておきましょう。
セッション残ってるよ問題が発生したらすぐにクリック!
これでセッション残ってるよ問題で悩まされることがなくなります。
また、セッション値を削除する部分にキャッシュを削除する機能もつければ、「キャッシュが残ってんじゃね?問題」も同時に解決することができます。こちらも便利なのでぜひ実装してみてください。
ただし、ログイン機能の実装後にこれを実行すると、当然ながらログアウトされてしまうので気をつけましょう。
※アプリケーションの完成後にこのスクリプトを消すのを忘れずに。。。