PHP::Session
Tatsuhiko Miyagawa<miyagwa@bulknews.net>
Livin’ On The EDGE, Co.,Ltd.
2003/01/31 Shibuya.pm Technical Talks

もくじn PHP::Session とはn なぜ必要なのかn PHPのセッション管理
n PHP::Session の実装
n 活用事例n 今後の展開PHP::Session とはDESCRIPTION
PHP::Session provides a way to read / write PHP4
session files, with which you can make your Perl
Application session shared with PHP4.
PHP::Session は PHP4 のセッションファイルの読み書きができ、これを利用することで、Perl アプリケーションのセッションをPHP4と共有することができる。

なぜ必要なのか

基本的には必要ない（えー必要になるケース
n 他社の製作したPHPコードに機能追加n PHPで書きたくない
n セッションの情報が必要

Perl から PHPセッションを操作!

PHPのセッション管理
n PHP3 では、PHPLIB というライブラリを使用する
n PHP4 では、ファイルベースのセッション管理がデフォルト (PHPLIBも使用可能)
n 現在ではPHP4が主流

PHP4のセッション管理実装
n /tmp/sess_${SESSION_ID} というファイルに書き出される(セキュアなのか?)n 排他処理は flock を使用
n 謎のエンコードフォーマット
baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";s:4:"done";}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";s:4:"done";}}!foo|エンコードフォーマット
Object

変数名

バイト数 クラス名

baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";s:4:"done";}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";s:4:"done";}}!foo|エンコードフォーマット (cont.)
key
string 長さ 値

value
string 長さ 値

baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";s:4:"done";}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";s:4:"done";}}!foo|エンコードフォーマット (cont.)
変数名 arrayint

baz|O:3:"foo":2:{s:3:"bar";s:2:"ok"値;s:3:"yes";s:4:"done";}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s: 添字
3:"yes";s:4:"done";}}!foo|エンコードフォーマット (cont.)

baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";s:4:"done";}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";s:4:"done";}}!foo|undef注意すること
n PHPには配列とハッシュの区別がない$a[1] = "foo";$a[2] = new baz;$a[3] = "bar";$a[4] = -1.2;$data['hi'] = 'foo';$data['foo'] = "bar";エンコードパーサの実装
n 基本はシンプルn 正規表現でイケる！
my $var_re = '(¥w+)¥|';
my $str_re = 's:¥d+:"(.*?)";';
my $int_re = 'i:(-?¥d+);';
my $dbl_re = 'd:(-?¥d+(?:¥.¥d+)?);';
my $arr_re = 'a:(¥d+):';
my $obj_re = 'O:¥d+:"(.*?)":¥d+:';my $nul_re = '(N);';
my $bool_re = 'b:([01]);';

エンコードパーサの実装(cont.)n ハッシュの実装は再帰的n 正規表現だけでは無理 (5.6 以上なら?)n PHP のソースは1文字ずつガリガリ• Perl っぽくない
n Parse::RecDescent• 重い (Parse::FastDescent?)• よくわからない<宣伝>「Perlデータマンジング」に詳しい</宣伝>エンコードパーサの実装 (cont.)n Text::Balanced を採用
n Damian Conway 作
n Parse::RecDescent の軽量版
n 対応するカッコを見つけてくれる• これを再帰的に実行すればOK
my $bracket = extract_bracketed($data, '{}');

PHP::Session の実装
n Serializer をPluggableな実装にした
n PHP では WDDX 方式もある(PHP::Session では未実装だが、WDDX.pmを使用すれば容易)
n Strategy Patternn sess_* ファイルがない場合はerror
n create => 1 オプションで生成

API
use PHP::Session;
my $session = PHP::Session->new($id);# session id
my $id = $session->id;# get/set session data
my $foo = $session->get('foo');$session->set(bar => $bar);# remove session data
$session->unregister('foo');API (cont.)# remove all session data
$session->unset;# check if data is registered$session->is_registered('bar');# save session data
$session->save;# destroy session$session->destroy;

PHPの実装n PHPの配列はPerlのハッシュn Perl(配列) > PHP (配列) > Perl(ハッシュ)n PHPのオブジェクトはPHP::Session::Object クラスに blessn _class キーにPHP側のクラス名を保持

Apache::Session::PHPn Apache::Sessionn セッション管理フレームワーク
n Store, Lock, Generate, Serializen Serialize と Store だけつくればよい
n Serialize: PHP::Session のモノ
n Store: ファイル名規則を PHPとあわせる(sess_${SESSION_ID})

tie %session, ‘Apache::Session::PHP’ …;

活用事例
n 使ってる人はいるのか？
n Bug Report や Patch はいっぱいくる

n Y! inc で採用(?)
n PHPをテンプレートエンジンとして使う
n セッションで変数の受け渡しを行う

n PHPのWebアプリケーションユニットテスト
n セッションをシミュレートテンプレートエンジン
use Apache::Cookie;
use Apache::Request;
use Digest::MD5 qw(md5_hex);
use PHP::Session;

my $r = Apache::Request->new(Apache->request);
my $sid = get_sid() || gen_sid();
my $sess = PHP::Session->new($sid, { create => 1 });$sess->set(name => 'miyagawa');$sess->set(email => 'miyagawa@bulknews.net');$sess->save();テンプレートエンジン (cont.)
my $cookie = Apache::Cookie->new($r,-name => 'PHPSESSID',-value => $sid, -path => '/',);$cookie->bake;$r->internal_redirect("/php-session/index.php");

sub get_sid {my %cookies = Apache::Cookie->fetch;
return ? $cookies{PHPSESSID} ?
$cookies{PHPSESSID}->value : undef;}テンプレートエンジン (cont.)<?php
session_start();?>Name: <?= $name ?><br>
Email: <?= $email ?><br>
SID: <?= $PHPSESSID ?>今後の展開n PHP::Session::MySQLn ストレージを MySQL にしただけ

n WDDX サポート
n Test::PHPn Inline::PHPn Tomcat::Session