アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

PHPでセッション情報が作成されるタイミングを調べてみました

皆さん、こんにちは。笹亀です。

MacBookAirの発表&発売やiPhone4の白の発売日が再々延期ということでいろいろな出来事がありました。白を待っていた自分にとっては残念なのと黒を買ってしまおうかと悩んでいます。

さて、本日は今まで何気なくセッションを使用していましたが、実際にファイルベースのセッションのやりとりでファイルが作成されるタイミングはどこなんだろう?っと疑問に思い、実際にPHPのセッションの作成されるファイルの流れについて調べてみました。
本日はその流れについてご紹介をさせていただきます。

PHPでセッションの情報の流れを調べるにはPHP本体のソースをみるのもいいですが、手軽に確認するために「session_set_save_handler」関数で調べることにします。
※所々にデバック確認用に出力しております。


<?php
function open($save_path, $session_name)
{
  echo 'test1';
  global $sess_save_path;
  $sess_save_path = $save_path;
  return(true);
}

function close()
{
  echo 'test2';
  return(true);
}

function read($id)
{
  echo 'test3';
  global $sess_save_path;

  $sess_file = "$sess_save_path/sess_$id";
  echo $sess_file . "";
  return (string) @file_get_contents($sess_file);
}

function write($id, $sess_data)
{

  echo 'test4';
  global $sess_save_path;

  $sess_file = "$sess_save_path/sess_$id";
  echo $sess_file . "";
  if ($fp = @fopen($sess_file, "w")) {
    $return = fwrite($fp, $sess_data);
    fclose($fp);
    return $return;
  } else {
    return(false);
  }

}

function destroy($id)
{
  echo 'test5';
  global $sess_save_path;

  $sess_file = "$sess_save_path/sess_$id";
  return(@unlink($sess_file));
}

function gc($maxlifetime)
{
  echo 'test6';
  global $sess_save_path;

  foreach (glob("$sess_save_path/sess_*") as $filename) {
    if (filemtime($filename) + $maxlifetime < time()) {
      @unlink($filename);
    }
  }
  return true;
}

session_set_save_handler("open", "close", "read", "write", "destroy", "gc");

echo 'session_start_defore';
session_start();
echo 'session_start_after';
echo $_COOKIE['PHPSESSID'] . "";
// proceed to use sessions normally
$_SESSION['test'] = $_SESSION['test'] + 1;
print print_r($_SESSION, true) . "";
?>



とりあえず作成したら1度、実行してみます。
初回アクセスの場合はローカルにPHPセッション名で保存されるCookieデータはありませんので、Cookieのデータを表示している箇所は空白になります。実行後はローカルにPHPセッション名のCookieデータが作成されます。当然、write関数を実行した後にはサーバー上にセッションファイルが作成されます。


もう一度実行します。今度はローカルにPHPセッション名で保存されるCookieデータがありますので、Cookieに保存されているセッションIDが表示されています。


上記の実行ではローカル側のCookieファイルがどこのタイミングで作成されているかわかりません。ではローカル側のCookieファイルがどこで作成されているかを確認します。

作成されるタイミングの候補は以下になります。
1.open関数前に作成されているのか?
2.read関数前に作成されているのか?
3.PHPスクリプト終了前に作成されているのか?
4.write関数前に作成するのか?

まずは1,2を試すためにread関数後にexitで処理をとめてCookieファイルを確認します。
 ※Cookieはリセットします

画像のようにCookieファイルは作成されておりません。

次に3,4を試すためにローカル側のCookie情報をスクリプトの途中で出力するようにして、
write関数の最初で処理をとめて確認します。
 ※Cookieはリセットします

画像のようにCookieファイルは作成されておりますが、Cookie情報が出力されていないことから、PHPスクリプト終了まではCookieが作成されていないですが、write関数前までにはローカルCookieが作成されていることがわかります。

今までのことを踏まえると下記の画像のようなセッションデータの作成する流れになっていることがわかります。


初回アクセスかセッション情報を一度でも作成したアクセスかどうかを確認することも可能になり、ログイン機能を例に考えると初回アクセスかログインしたユーザでタイムアウトなどで無効になったCookieデータかの判断が可能になります。
しっかりと仕組みと構造を理解しておくと利用できる幅がひろがりとてもためになりました。