memcachedにsessionを保存してみる

前回のエントリ(http://d.hatena.ne.jp/clmind/20090506/1241617408)でmemcachedを入れてみたので、phpでセッションをmemcachedに保存してみました。セッション保存関数を再定義するにはsession_set_save_handlerに各メソッドをコールバック関数として引数で渡せば良いみたいです。

http://search.net-newbie.com/php/function.session-set-save-handler.html

試しに作ったのは以下です。良くある訪問回数を出力するスクリプトです。殴り書きであんまりきれいなコードじゃないので参考にならないと思いますが、最後にコードもはっつけておきます。Memcacheクラスを継承して再定義のみ行うラッパークラスにした方が奇麗かな。そもそもセッションを丸々いれるよりはUser IDなんかのみを普通ににセッションに登録して、それをキーにmemcachedに登録したデータを取り出すとかの方が実際に使うなら奇麗かもしれないですね。

http://www.ivory-mind.com/memcached/

データはSession IDをキーとしてmemcachedに登録されます。実際に登録してみたデータをtelnetで叩いて取り出してみたところこんな感じになりました。countがintegerとして登録されています。

# telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
get 7qavb19c03q9o969kum88rp412
VALUE 7qavb19c03q9o969kum88rp412 0 11
count|i:1;
END
コード
<?php

dl("memcache.so");

$mysess = new MySessionHandler();

session_start();
$count = $mysess->get_count();
$message = $mysess->get_message();
$id = session_id();

$html = <<< EOH




    セッションテスト



${count}回目の訪問ですね。 ${message}
Session ID: ${id} EOH; echo $html; class MySessionHandler { private $memcache; private $server; private $port; private $expire; function __construct($server, $port, $expire) { //セッション関数をオーバーラップ session_set_save_handler( array(&$this, "open"), array(&$this, "close"), array(&$this, "read"), array(&$this, "write"), array(&$this, "destroy"), array(&$this, "gc") ); $this->memcache = new Memcache(); $this->server = "127.0.0.1"; $this->port = "11211"; $this->expire = ini_get('session.gc_maxlifetime'); //セッションストアをオーバーラップ session_save_path($this->server); } function __destruct() { } function get_count() { if(isset( $_SESSION["count"])) { $_SESSION[ "count" ]++; } else { $_SESSION[ "count" ] = 1; } $count = $_SESSION["count"]; return $count; } function get_message() { if(!isset( $_SESSION["count"])) { return "初めてですか。いらっしゃい。"; } $count = $_SESSION["count"]; if($count < 10) { return "またお会いしましたね。ありがとうございます。"; }else if($count < 100) { return "xxxxxxxxxxxxxxxxxxxxxxxx"; } return "xxxxxxxxxxxxxxxxxxxxx"; } // ラッパー用関数 function open($save_path, $session_name) { $this->memcache->addServer($this->server, $this->port); $this->memcache->pconnect($this->server, $this->port); return(true); } function close() { return(true); } function read($id) { $data = $this->memcache->get($id); return $data; } function write($id, $sess_data) { return $this->memcache->set($id, $sess_data, 0, $this->expire); } function destroy($id) { return $memcache->delete($id); } function gc($maxlifetime) { return true; } } ?>