複数のWebサーバを構築して、個々のWebサーバ内で同一のセッションを使用することはよくあることです。最近のロードバランサには複数のWebサーバを管理する際に一緒にセッションを保持してくれる機能がついているものもあります。そのような機器は値段が高くて、コストを考えると悩ましいところです。

 今回はWebサーバを複数持つような場合でも手軽にDBにセッションを保存して管理する方法をご紹介します。

 今回、セッションハンドラを使用する目的は、複数のWebサーバ間で同一セッションを管理することです。

 まずはセッションデータを保存するテーブルを作成します。テーブル名、フィールド名などは、好きな名前で作成してかまいません。

CREATE TABLE session_t (
session_id VARCHAR(50) NOT NULL,
session_data text,
session_createdate datetime,
PRIMARY KEY (session_id));

 次にセッションハンドラの関数を作成します。

<?php
function connect_db() {
  
$db_connect 
    
mysql_connect("host_name""user_name""password"
    or die(
"Could not connect");
  return 
$db_connect;
}


function 
open ($save_path$session_name) {
  global 
$db;
  
$db connect_db();
  return 
true;
}

function 
close() {
  return 
true;
}

function 
read ($id) {
  global 
$db;
  
mysql_select_db("db_name");
    
  
$result mysql_query("SELECT * 
                         FROM session_t 
                         WHERE session_id='{$id}'"
);
  if(
mysql_num_rows($result) == 1){
    
$row mysql_fetch_array($result);
    return 
$row['session_data'];
  } else {
    return 
"";
  }
}

function 
write ($id$sess_data) {
  global 
$db;
  
mysql_select_db("db_name");
  
$result mysql_query("SELECT * 
                         FROM session_t 
                         WHERE session_id='{$id}'"
);
  if(
mysql_num_rows($result) == 1){
    
$result mysql_query("UPDATE session_t 
                           SET session_data='{$sess_data}' 
                           WHERE session_id='{$id}'"
);
  }else{
    
$date date('Y-m-d H:i:s');
    
$result mysql_query("INSERT INTO session_t 
                           VALUES('{$id}' , 
                                  '{$sess_data}' ,'{$date}')"
);
  }
  return 
true;
}

function 
destroy ($id) {
  global 
$db;
  
mysql_select_db("db_name");
  
$result mysql_query("DELETE from session_t 
                         WHERE session_id='{$id}'"
);

  return 
true;
    
}

function 
gc ($maxlife_time) {
  return 
true;
}

session_set_save_handler 
    
("open""close""read""write""destroy""gc");
?>

 セッションハンドラの作成準備が完了したら、セッションを保存して実行するスクリプトを作成します。

<?php
include_once("session_handler.php");

session_start();
if (
$_POST["submit"]) {
  
print_r($_SESSION);
}else{
  
$_SESSION["name"]="1234567";
  
$_SESSION["id"]="123456789";
}
?>
<html>
<body>
<form action="index.php" method="post">
<input type="submit" name="submit" value="TEST">
</form>
</body>
</html>

 実行後にセッションのテーブルを確認すると、セッションデータが格納されて、読み込まれたり書き込まれていることがわかるとおもいます。このようにデータベースさえ使用できれば、セッションを管理することができ、Webサーバが複数ある場合でも共通のセッションを使用することが可能になります。

 ただ、セッションハンドラはセッションをデータベースで管理することができますが、読み込んだり、書き込んだりとデータベースへのアクセスが増えてしまい、データベースに負荷をかけてしまうのが難点です。

 今回は、セッションハンドラとデータベースを使用することでセッションの共通化を行いましたが、ほかにも、NFS(UNIXシステムで利用されるファイル共有システム)などを使用することでも、セッションの共通化問題を解決させることもできます。

 複数のWebサーバを使用するときには、手軽に実装できるセッションハンドラをお使いになってみてはいかがでしょうか。



(アシアル 笹亀弘)


この記事は、アシアルが運営するPHP開発者のためのポータル&コミュニティサイト「PHPプロ!」で毎週配信しているPHP・TIPSメーリングリストを再録したものです。
同サイトでは、他にもPHP最新ニュースや、困ったときのQ&A掲示板、初心者向けのPHP講座など、PHP開発者をサポートする情報を掲載しています。