Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

php session_handler pecl☆magica

No description
by

rti 7743

on 16 February 2011

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of php session_handler pecl☆magica

by rti @super_rti http://rtilabs.net/ 複数台でのセッション保持のためには
セッションストアほしいですね。 load balancer server server server session store session store replication セッション保持の戦略 方法 サーバ数 速度 GC(ガペコレ) repl(レプリ) ストレージ
file 1台のみ fast Yes No disk
file+L7switch 1台~ fast Yes No disk
db 2台~ slow Yes Yes disk
memcached 1台~ fast Yes No memory
replacted 2台~ fast Yes Yes memory
tokyotyrant 1台~ fast No Yes disk
kumofs 2台~ fast ? Yes disk 高速で、レプリケーションができて、
鯖が落ちてもある程度はデータが残っていて欲しいかなぁ。

だけど、予算がないから、大規模構成は無理だお。 tokyo tyrant tokyo tyrant ってバランスがいいよね。 だけど、PHPで導入するコード作るのめんどい。
ガペコレの設定もめんどい。
pecl php_tokyotyrantってのがある 作った人
mkoppanen (Mikko Koppanen)さん http://github.com/mkoppanen で、マニュアルとかソースとか見ていると、 あれ、設定って2行だけでOKなの? <?php
ini_set('session.save_handler', 'tokyo_tyrant');
ini_set('session.save_path' , 'tcp://127.0.0.1:1978');
?> or php.ini session.save_handler = tokyo_tyrant
session.save_path = tcp://127.0.0.1:1978 あれ、GC入っているぢゃん。 /etc/php.d/tokyotyrant.ini ----------tokyotyrant.ini-------------------
extension=tokyo_tyrant.so
[tokyo_tyrant]
tokyo_tyrant.php_expiration=1
-------------------------------------------- これはすごい。
いれてみるべー pecl install php tokyo tyrant.0.5.0 インストール方法 現在だと 0.5.0 が最新
当時は 0.4.0 だった。
http://pecl.php.net/package/tokyo_tyrant で、
今回は ver 0.4.0 の時に
あったバグを直した話です。 現在の ver 0.5.0では
このバグはすべて修正されています。 pecl install php tokyo tyrant.0.4.0 昔の話をしよう。 バグがある0.4.0を入れる。 インストールしたから、
apacheにアクセスして動作を見よう! あれ、、、画面がシロイヨ -----------test.php------------
<?php
//tokyo tyrant を利用する
ini_set('session.save_handler', 'tokyo_tyrant');
ini_set('session.save_path', 'tcp://127.0.0.1:1978');

session_start();

$a = (int)@$_SESSION['a'];
@$_SESSION['a'] = $a + 1;

echo "Count : {$a}";
?>
--------------------------------- apacheのエラーログを見ると tail /var/log/httpd/error.log [Tue Sep 21 00:05:25 2010] [notice] child pid 14590 exit signal Segmentation fault (11)
[Tue Sep 21 00:05:25 2010] [notice] child pid 14591 exit signal Segmentation fault (11)
[Tue Sep 21 00:05:25 2010] [notice] child pid 14592 exit signal Segmentation fault (11) 最新版ではクラッシュではなく、
エラーメッセージが表示されます。 tokyotyrantの動作モードに問題 pecl php tokyo tyrantは、
tch → tct モードでしか動かない。 vi /usr/local/sbin/ttservctl

dbname="$basedir/casket.tch#bnum=1000000"

dbname="$basedir/casket.tct#bnum=1000000"
もう一度トライ。 今度はうまくいった。 ログイン処理を作ってみよう。 ログイン処理は、
セッションハイジャック対策とか
ふつーやりますよね? session_regenerate_id session_start();

if ( isset ( $_GET['renew'] ) )
{
$old_session_id = session_id();
$result_session_regenerate_id =
session_regenerate_id(TRUE);
$new_session_id = session_id();

echo "REGENERATE!!<br>\r\n";
}
else
{
$new_session_id = session_id();
} apacheのエラーログを見ると tail /var/log/httpd/error.log [Tue Sep 21 00:08:11 2010] [notice] child pid 14595 exit signal Segmentation fault (11) 最新版ではちゃんと動作します。 私、
こういう時
どうすればいいか
わからないの。 phpのセッション作り直しが
消して作るという強引な実装で、
それに php_tokyotyrantが対応して
いないため。 php 5.3.2 session.c static PHP_FUNCTION(session_regenerate_id)
{
~skip 中略~

if (PS(session_status) == php_session_active) {
///消して、
if (PS(id)) {
if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
RETURN_FALSE;
}
efree(PS(id));
PS(id) = NULL;
}

//作り直す
PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
~skip 中略~
}
} delしてnewするから
php_tokyotyrantのなかでの
参照が狂っちゃうのね。 また、apacheが落ちたー /* Session id is being regenerated. Need to copy some data */
if (PS(session_status) == php_session_active) {
TT_SESS_DATA;

//ここでクラッシュ CARSH!!!!!!!!!!!!!!!!!!
//session is NULL!!!!!!
/* Use old values unless regeneration is forced */
if (session->remap == 0) {
idx = session->idx;
pk = estrdup(session->pk);
current_rand = estrdup(session->sess_rand);
} else {
session->remap = 0;
}
} 落ちたところを見てみる。 根本的な原因 gdb で
attach
してみるといいと
思うよ。 あれ、、、画面がシロイヨ gdbでアタッチする 1.めんどいのでapacheのフォークを最小にする vi /etc/httpd/conf/httpd.conf StartServers 1
MinSpareServers 1
MaxSpareServers 1
MaxClients 1 2.httpd停止 /etc/init.d/httpd stop 3. gdbでアタッチ gdb httpd 4.アタッチしながら実行 (gdb) run -X httpdが動作するので、
ブラウザを操作してクラッシュさせる。 Starting program: /usr/sbin/apache2
Starting program: /usr/sbin/httpd -X
[Thread debugging using libthread_db enabled] 5.クラッシュ再現 Program received signal SIGSEGV, Segmentation fault. 6.バックトレースを見る (gdb) bt #0 ps_create_sid_tokyo_tyrant (mod_data=0xb7d4e830, newlen=0x0)
at /var/tmp/tokyo_tyrant/session.c:51
#1 0xb7ad7ea8 in ?? () from /etc/httpd/modules/libphp5.so
#2 0xb7c379a1 in ?? () from /etc/httpd/modules/libphp5.so
#3 0xb7c0db7a in execute () from /etc/httpd/modules/libphp5.so
#4 0xb7be7a2d in zend_execute_scripts () from /etc/httpd/modules/libphp5.so
#5 0xb7b91088 in php_execute_script () from /etc/httpd/modules/libphp5.so
#6 0xb7c74380 in ?? () from /etc/httpd/modules/libphp5.so
#7 0x00437a4d in ap_run_handler ()
#8 0x0043b413 in ap_invoke_handler ()
#9 0x0044752e in ap_process_request ()
#10 0x004442cf in ?? ()
#11 0x0043f94d in ap_run_process_connection ()
#12 0x0043fa4c in ap_process_connection ()
#13 0x0044be14 in ?? ()
#14 0x0044c084 in ?? ()
#15 0x0044cf99 in ap_mpm_run ()
#16 0x00423157 in main ()
ね、簡単でしょ? session再構築ボタンを
ぽちっとな。 こんにちはー 自己紹介 ハンドル: rti
肩書き: シーランド公国伯爵 新潟アクセス修飾子のご提案 (php)
数式を一切使わないSVM話(データマイニング)
とある関数の接合部SEXYHOOK(C++)
萌え萌えCSS / 回転 (javascript) 去年の主なプレゼン インフラ設計から企画、開発まで
いわいる何でも屋さんデス。 本当はソフトウェアの研究がしたいんだけどなぁ gdb !? pecl tokyotyrantってとっても便利だなって もう gdbも怖くない phpカンファレンスであったような 結構強引な実装 僕は gdb が嫌いだ。

だけど、好きになれるかもしれない。 だけど、
行レベルのトレース
とかやってられない そんな人のために、
コピペで使える
ロガー作りました。 printfデバッグのお供に http://d.hatena.ne.jp/rti7743/20100604/1275665317 MYLOG("ここまでやってきた %d",123); tail /tmp/mydebug ここまでやってきた 123@ /home/rti/tokyo_tyrant-0.4.0/session.c:66(ps_create_sid_tokyo_tyrant)
MYLOGBT(); tail /tmp/mydebug ==== start backtrace === @ /home/rti/tokyo_tyrant-0.4.0/session.c:117(ps_create_sid_tokyo_tyrant)
0 : /usr/lib/php5/20060613+lfs/tokyo_tyrant.so(mylogBK+0x80) [0xb60def50]
1 : /usr/lib/php5/20060613+lfs/tokyo_tyrant.so(ps_create_sid_tokyo_tyrant+0x5a) [0xb60df13a]
2 : /usr/lib/apache2/modules/libphp5.so(zif_session_regenerate_id+0xf0) [0xb6e1f6a0]

中略

18 : /usr/sbin/apache2(ap_mpm_run+0x5fa) [0x809073a]
19 : /usr/sbin/apache2(main+0xa50) [0x8066f10]
20 : /lib/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb7dbd455]
21 : /usr/sbin/apache2(apr_global_mutex_lock+0x31) [0x8065ec1]

==== end backtrace === 話がずれた。。 orz で、落ちないように修正したパッチを送ったら、修正されました。 めでたし めでたし。 ・・・・ ってこれだけぢゃ
満足しないよね。 っていうか、これなによ!!
<?php
ini_set('session.save_handler', 'tokyo_tyrant');
ini_set('session.save_path' , 'tcp://127.0.0.1:1978');
?> なぜこれだけで、
セッションハンドラーができるのか? gdb !? phpもCもあるんだよ Cで書かないなんてあるわけない こんなの絶対おかしいよ カスタムの session_handler って
いったら PHP で
つくるものではなかったのか? <?php
require_once '/TokyoTyrant/Session.class.php';

function open($save_path, $session_name)
{
return TokyoTyrant_Session::connect();
}

function read($session_id)
{
return TokyoTyrant_Session::get($session_id);
}

中略

//カスタムなセッションハンドラー登録
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc'); tokyotyrant sessionの例 pecl 拡張でも
session_handler をかけます。
そして session_handler を実装している
pecl モジュールは、

php_ini('session_handler=hogehoge'); を

することだけで簡単に利用できます。 pecl モジュールな
session_handlerの
利点と欠点 1.C言語で書くので高速

2.connection poolや
HA等の高度なことができる

3.peclを使えれば導入が
非常に簡単 利点 欠点 1.C言語で書くので
ちょっと敷居が高い

2.あんまり日本語の資料が
公開されていない気がする 1.C言語で書くので高速

   (゚∀゚)ノキュンキュン!



2.connection poolや
HA等の高度なことができる

  高度高度




3.peclを使えれば導入が
非常に簡単

  楽ちんサイコー 利点 peclなsession_handler は、
(導入コストが)安い、
(実行コストが)早い、
(高度なことができて)うまい 欠点 1.C言語で書くので
ちょっと敷居が高い

C言語は
あなたの友人です。。



2.あんまり日本語の資料が
公開されていない気がする

公開してやんよ ←今ここ こんなの絶対おかしいよ
って質問タイーム 利点の方が多い!!
大丈夫。きっとかけるよ。
足りない分は勇気でカバーだ
pecl モジュールな
session_handler の書き方。 いつもの
pecl モジュール
+ セッション処理用の関数を実装して
PS_CREATE_SID_FUNC(modulename)
,PS_OPEN_FUNC(modulename)
,PS_CLOSE_FUNC(modulename)
,PS_READ_FUNC(modulename)
,PS_WRITE_FUNC(modulename)
,PS_DESTROY_FUNC(modulename)
,PS_GC_FUNC(modulename) + ジャンプテーブルを作って
ps_module ps_mod_mytest =
{
PS_MOD(modulename)
}; + php_session_register_moduleで
登録するだけ
PHP_MINIT_FUNCTION(modulename)
{
php_session_register_module
(&ps_mod_mytest);
} いつもの
pecl モジュール
ext_skel が動作する
環境を作ってください。 パッケージ
yum -y install m4 autoconf automake libtool gcc php-devel


phpのソース
wget http://www.php.net/get/php-5.3.5.tar.bz2/from/jp.php.net/mirror
tar Ixvf php-5.3.5.tar.bz2


./ext_skelで雛形を作ります。
今回は、 mytestという名前で作ります。
cd php-5.3.5/ext
./ext_skel --extname=mytest --proto=mytest.proto



詳しくは 「魔法少女好きだったらわかるphp拡張の作り方。 」とかどうぞ。
http://d.hatena.ne.jp/rti7743/20110212/1297535546 セッション処理用の関数を実装して
PS_CREATE_SID_FUNC(modulename)
,PS_OPEN_FUNC(modulename)
,PS_CLOSE_FUNC(modulename)
,PS_READ_FUNC(modulename)
,PS_WRITE_FUNC(modulename)
,PS_DESTROY_FUNC(modulename)
,PS_GC_FUNC(modulename) 今回は、/tmp/ の下にファイルを作る
という php のディフォルトの
セッションストアを簡略化したものを
実装したいと思います。 mytest_session.c と mytest_session.h の
2つのファイルを作成します。 mytest_session.h #ifndef MYTEST_SESSION_H
#define MYTEST_SESSION_H

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_mytest.h"
#include <fcntl.h>

/* セッション管理用のデータ構造 */
typedef struct {
char * filename;
char * save_path;
} php_mytest_session;

#endif //MYTEST_SESSION_H mytest_session.c #include "mytest_session.h"

/**
セッション用のユニークなランダムな文字列 sid を返す.
目的
1.セッション用のsid (ランダムなユニークな文字列)を emalloc して返す.

注意
一見単純そうだが、session_regenerate_idの 罠がある。

ここが呼ばれ時、セッションが有効な場合と無効な場合がある。
また一見有効だが、実は無効など、、複雑な場合がある。
つまり、
動作1.まったくサラ地の状態でセッションを作る場合 (大部分の場合)
動作2.セッションは有効で利用できるが、新たに作り直す場合
動作3.セッションは有効とあるが、実は無効なデータ NULL が入っている場合 session_regenerate_id(TRUE)

サーバに対する connection pool等をしている場合は要注意である。
詳しくは、 pecl tokyotyrant の session.c とかを見ればいいよ.
定義
char *ps_create_sid_##x(void **mod_data, int *newlen TSRMLS_DC)
*/
PS_CREATE_SID_FUNC(mytest)
{
/*
php本体のphp_session_create_idを呼び出してユニークな SID をつくってもらう。
自分で作ってもいいんだろうけど、、、
*/
char *sid = php_session_create_id(PS(mod_data), NULL TSRMLS_CC);
if (!sid)
{
return NULL;
}
return sid;
} /**
セッション管理が開始されるとき呼ばれる。
目的
1.セッション用のメモリの確保
session = emalloc( sizeof( php_mytest_session ) );
PS_SET_MOD_DATA(session)
以後 PS_GET_MOD_DATA() で取り出せる.
2.格納する場所の初期化を行う。 PS(save_path)

注意
PS_OPEN_FUNCと名前があるが、
ここでは、sid がまだわからないので、セッションを open できない。
なお、connection pool等をここで開始する実装もある。
定義
int ps_open_##x(void **mod_data, const char *save_path, const char *session_name TSRMLS_DC)
*/
PS_OPEN_FUNC(mytest)
{
/* セッション用のメモリを確保 */
php_mytest_session * session = (php_mytest_session*)emalloc( sizeof( php_mytest_session ) );
if (!session)
{
PS_SET_MOD_DATA(NULL);
return FAILURE;
}
/* セッションをセーブするパス */
session->save_path = estrndup( save_path, strlen( save_path ));

/* サーバタイプの場合ここで接続することもできる. */

/* セッションデータの記録 */
PS_SET_MOD_DATA(session);
return SUCCESS;
} /**
セッション管理を開放する時に呼ばれる.
目的
1.セッション用のメモリの開放
PS_OPEN_FUNC で確保した領域の開放を行う。

注意
あとででくる PS_DESTORY_FUNC と紛らわしいが、
Close の目的は、 Openの逆である。
定義
int ps_close_##x(void **mod_data TSRMLS_DC)
*/
PS_CLOSE_FUNC(mytest)
{
/* セッション管理データの読み出し. */
php_mytest_session * session = PS_GET_MOD_DATA();
if (!session)
{
/* closeなので甘めに. */
return SUCCESS;
}

/* PS_OPEN_FUNCで確保したデータを解放. */
efree(session->save_path);
efree(session);

/* データには、何もありませんよ。 */
session = NULL;
PS_SET_MOD_DATA(NULL);

return SUCCESS;
} /*
session_handler を実現するためのおまじない.
これは、マクロ展開されて、 PS_CREATE_SID_FUNC などで定義した関数へのルックアップテーブルになるよ。
定義
typedef struct ps_module_struct {
const char *s_name;
int (*s_open)(PS_OPEN_ARGS);
int (*s_close)(PS_CLOSE_ARGS);
int (*s_read)(PS_READ_ARGS);
int (*s_write)(PS_WRITE_ARGS);
int (*s_destroy)(PS_DESTROY_ARGS);
int (*s_gc)(PS_GC_ARGS);
char *(*s_create_sid)(PS_CREATE_SID_ARGS);
} ps_module;
*/
ps_module ps_mod_mytest = {
PS_MOD(mytest)
};
/*
ガページコレクションを行う。
目的
1.古いデータファイルを削除する
2.古いデータの定義は、引数 maxlifetime (秒)を過ぎたデータである。
注意
PHPのセッションは、特定のユーザセッションを利用して、
セッションの GC を起動する。
重いGCを動かすとユーザ体験の阻害になる可能性がある。
GC が発動する確率は、 PS(gc_probability) / PS(gc_divisor) である。
定義
int ps_gc_##x(void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC)
*/
PS_GC_FUNC(mytest)
{
/* セッション管理データの読み出し.
save_path を取り出すためだけに利用する... */
php_mytest_session * session = PS_GET_MOD_DATA();

~長いので中略~

/* 現在時刻。
この時刻をベースに、 引数 maxlifetime (秒) 過ぎているデータを削除していく. */
time_t now = time(NULL);
char filename[MAXPATHLEN];

struct dirent *dire;
while ((dire = readdir(dir)) != NULL )
{
/* セッションデータ以外は無視する. */
if ( strcmp(dire->d_name , "mytest.session.") != 0)
{
continue;
}

~長いので中略~

/* 古いデータ? */
if ((now - sbuf.st_mtime) <= maxlifetime)
{
/* 古くない. */
continue;
}

/* データを消去する. */
unlink(filename);
}

return SUCCESS;
}
+ + mytest_session.c の末尾 ジャンプテーブルを作って
ps_module ps_mod_mytest =
{
PS_MOD(modulename)
}; php_session_register_moduleで
登録するだけ
PHP_MINIT_FUNCTION(modulename)
{
php_session_register_module
(&ps_mod_mytest);
} + mytest.cのPHP_MINIT_FUNCTION PHP_MINIT_FUNCTION(mytest)
{
/* If you have INI entries, uncomment these lines
REGISTER_INI_ENTRIES();
*/

//セッションハンドらーを実装していますよー
php_session_register_module(&ps_mod_mytest);

return SUCCESS;
} = session_handlerを
実装した、
pecl モジュール!! 我慢強い人のための
peclでsession_handlerを作る。

http://d.hatena.ne.jp/rti7743/20110213/1297548206 長ったらしいので、
動くもののサンプルあるよ! 完成したので、
インストールして組み込んでみよう。 phpize ; ./configure ; make ; make install

echo "extension=mytest.so" > /etc/php.d/mytest.ini

/etc/init.d/httpd restart tokyotyrantの
テストで使ってルーチンで
試してみよう! <?php

ini_set('session.save_handler', 'mytest');
ini_set('session.save_path', '/tmp');

以下略 動いたぁぁぁぁぁあああ ちゃんとセッションファイルも
mytestで作成されています。 簡単だね。 まとめ 僕と契約して、
session_handlerを搭載した
pecl モジュール作ってよ! えんいー php session_handler
pecl ☆ magica このプレゼンは
頭をmogmogされることもないし、
敏腕セールスマンもいない、
お子様でも安心してご覧になれる、
極めて健全なプレゼンです。(半分嘘) /**
セッションに対する読み込み
目的
1.セッションデータ key が指すデータを、PS_OPEN_FUNC で準備した
PS_GET_MOD_DATA() を使って読み込む
2.読み込んだデータ *val に書きこむ。
3.読み込んだデータ長さは *vallen に書く.
定義
int ps_read_##x(void **mod_data, const char *key, char **val, int *vallen TSRMLS_DC)
*/
PS_READ_FUNC(mytest)
{
/* セッション管理データの読み出し. */
php_mytest_session * session = PS_GET_MOD_DATA();
if (!session)
{
return FAILURE;
}

/* 引数 key でイタヅラされないように. */
if ( ! checkSessionKey(key) )
{
return FAILURE;
}

/* 引数 key が指し示すデータを開く. */
char filename[MAXPATHLEN];
snprintf(filename,MAXPATHLEN,"%s/mytest.session.%s.txt",session->save_path , key );
filename[MAXPATHLEN - 1] = '\0';

FILE * fp = fopen(filename,"ab+");
if (!fp)
{
return FAILURE;
}
flock(fp, LOCK_EX);

//先頭に戻す.
rewind(fp);

~中略~

/* データ長分の領域を確保.*/
char* readbuffer = (char*)emalloc(sbuf.st_size);
int readsize = fread(readbuffer,1,sbuf.st_size,fp);

/* もうデータは不要なのでファイルを閉じる. */
flock(fp, LOCK_UN);
fclose(fp);

~中略~

/* 読み込んだデータを返す. (readbufferを開放するのは、phpさんの責任!!) */
*val = readbuffer;
*vallen = readsize;

return SUCCESS;
} /**
セッションに対する書き込み
目的
1.セッションデータ key のデータ val を、PS_OPEN_FUNC で準備した
PS_GET_MOD_DATA() を使って書きこむ
2.データ val のデータの長さ vallen になる.
定義
int ps_write_##x(void **mod_data, const char *key, const char *val, const int vallen TSRMLS_DC)
*/
PS_WRITE_FUNC(mytest)
{
/* セッション管理データの読み出し. */
php_mytest_session * session = PS_GET_MOD_DATA();
if (!session)
{
return FAILURE;
}

/* 引数 key でイタヅラされないように. */
if ( ! checkSessionKey(key) )
{
return FAILURE;
}

/* 引数 key が指し示すデータを開く. */
char filename[MAXPATHLEN];
snprintf(filename,MAXPATHLEN,"%s/mytest.session.%s.txt",session->save_path , key );
filename[MAXPATHLEN - 1] = '\0';

FILE * fp = fopen(filename,"wb+");
if (!fp)
{
return FAILURE;
}
flock(fp, LOCK_EX);

/* データ長分の領域を確保. */
int writesize = fwrite(val,1,vallen,fp);

/* もうデータは不要なのでファイルを閉じる. */
flock(fp, LOCK_UN);
fclose(fp);

~中略~

return SUCCESS;
} /**
セッションデータを削除する
目的
1.セッションデータ key のデータを削除する
注意
PS_CLOSE_FUNCとは違い、PS_SET_MOD_DATA(NULL)する「わけではない」。
あくまでも、 key のデータを消去するだけである。
定義
int ps_delete_##x(void **mod_data, const char *key TSRMLS_DC)
*/
PS_DESTROY_FUNC(mytest)
{
/* セッション管理データの読み出し. */
php_mytest_session * session = PS_GET_MOD_DATA();
if (!session)
{
return FAILURE;
}

/* 引数 key でイタヅラされないように. */
if ( ! checkSessionKey(key) )
{
return FAILURE;
}

/* 引数 key が指し示すデータを開く. */
char filename[MAXPATHLEN];
snprintf(filename,MAXPATHLEN,"%s/mytest.session.%s.txt",session->save_path , key );
filename[MAXPATHLEN - 1] = '\0';

/* データ key のデータが入っているファイルを削除する. */
unlink(filename);

return SUCCESS;
}
session rename 的な実装が欲しかったね レイアウトは自由 /etc/php.ini
#1/1000 の確率で
#GCを起動する
session.gc_probability = 1
session.gc_divisor = 1000

#この時間すぎた
#セッションを消す。単位 秒
session.gc_maxlifetime = 1440 PHPAPI void php_session_start(TSRMLS_D) /* {{{ */

~中略~

if (PS(mod_data) && PS(gc_probability) > 0) {
int nrdels = -1;

nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg(TSRMLS_C));
if (nrand < PS(gc_probability)) {
PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels TSRMLS_CC);
#ifdef SESSION_DEBUG
if (nrdels != -1) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "purged %d expired session objects", nrdels);
}
#endif
}
}
session_handlerを
実装した、
pecl モジュール!! = session GC発動
Full transcript