woshidan's blog

あいとゆうきとITと、とっておきの話。

phpのsession_start()について

とりあえず、長くなったので最初の三つの疑問

  • セッションを開始して、セッションIDをあるphpで発行する→他のページへ遷移したとき、どうそのIDを呼び出すのか、あるいは引き継ぐのか?
  • 一つのセッションへの重複アクセスを避けるためにその都度session_write_close()を書こうか、と思っているが、その場合特に気になる……
  • 一旦そのホームページを閉じて、また最近のタブを表示とかで開いた場合、そのセッションってどうなってるのか?

について、個別に答えようかと思ったのですが、疑問が生じた原因が一つだったようなので、まとめて。

 

細かいことは後にして、先に昨日の疑問のうち三つに答えを出しておくと

・セッションを開始すると自動的に発行されるセッションIDはCookieに一定時間保存される。その次のページからCookie['PHPSESSID']で参照することができるし、session_start()を呼び出すと自動的にセッションIDがセットされているか調べるようになっているので、とりあえずID引継ぎのために特別に何かする必要はあまりない。

・session_write_close()は現在ブラウザで保存しているセッションIDに対応するデータへアクセスする処理が含まれるスクリプト、データへアクセスする処理が終了したという宣言を行うような処理。よって、呼び出したからと言って、そこで同じセッションIDが使えなくなる(むしろその都度宣言しなくなると同時アクセスなどが起こって処理が中断されるスクリプトが現れる)ということはない。

 セッションIDが使えなくなるのはセッションIDを保存しているCookieの有効期限が切れたとき。たとえば、ログアウトでセッションIDの有効期限を切りたいときに有効期限を過去に設定する。

・一旦タブを閉じて再びサイトを開きなおした場合。そのドメイン内で保存するように設定されているCookieは有効期限まで保存されているので、開きなおしても有効期限内ならセッションを使うときは同じセッションIDを用いることになると思われる。

になりました。

 

で、これらの疑問は結局はsession_start()の挙動が分かっていないことが3つの疑問が生じる原因だったようです。

 

こちら(http://doremi.s206.xrea.com/php/tips/session.html)を参考。

 

session_start()の挙動

session_start()でセッションを開始すると、

1.セッションIDがクッキーなどに存在する場合、そのIDのセッションを復帰

(つまり、サーバー上からそのセッションIDに対応する仮想配列を引っ張ってきてセッション配列にセットする)

2.それ以外の場合、新しいセッションIDを発行してクッキー保存させる

 

Cookieとかをいじっちゃって架空のセッションIDを送られた場合、

架空のセッションIDに基づいて配列を作っちゃう、ということなので、注意する。

 

で、開始されたセッションを引き継ぐ、というか、

session_start()で発行されたセッションIDを引き継ぐためには、

セッションIDはPHPSESSIDという名前でCookieに保存されていてます(=ブラウザ側で自動的にしばらく保存されている)ので、

$_COOKIE['PHPSESSID']を次のページ以降で読み込めばよいです。

 

保存時間やセッションIDを保管しておくドメインの範囲は

ドメインで扱うクッキー丸ごと単位になりますが、

session_set_cookie_params()で指定できます。

session_set_cookie_params()は、http://www.php.net/manual/ja/function.session-set-cookie-params.phpによれば、

void session_set_cookie_params ( int $lifetime [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]] )

な具合で、複数のパラメータを取る関数です。

いくつか引数が指定できるのですが、デフォルト値がphp.iniにあるため、

とりあえずは、session_start()の前に呼び出して、

一個目の引数だけ

session_set_cookie_params($lifetime);

のようにその都度保存時間を指定するようにする、のでいいのでしょうかね……。

 

開始されたセッションとかいう言い方で自分はややこしく感じていたのだけど、

一旦一つのセッションIDと紐付けされた連想配列$_SESSIONに対してアクセスするスクリプトを決めて、

そのスクリプトの処理がはじめる=セッションを開始するってことだと思うと理解しやすい気がしています。。

 

で、セッションを終了する(セッションを閉じる)、というのは、その仮想配列$_SESSIONにアクセスしているスクリプトが終了する、という意味で、

セッションをなるべく処理を行うごとに終了するようにする、というのは、

同時にアクセスを防ぐために複数アクセスが行われそうになったら二個目以降のスクリプトの処理を行わない、

という仕様があるので、そのスクリプトが行われなくなるような事態を避けられるように、なんとなく関数な

どを続けずすぐ関数を閉じる、あるいはセッションの終了を宣言する、という意味だといまは理解しています。

 

また、閉じられたセッションがある、というのは、そのセッションIDで呼び出される仮想配列をいじっていない状態になっているセッションIDがあるっていう状態のことっぽいです。

 

で、サイトを閉じても前の項目で言った、セッションの保存時間の間が、セッションIDはクライアント側のブラウザに、セッションIDと関連付けられているデータはサーバ側に(これは上の関数でなくてphp.iniの中の別のパラメータで保存時間を指定する→http://monolog.spanstyle.com/2005/07/session.html)保存されていて、

セッションが閉じられていれば、また別のphpのスクリプトからそのセッションを再開する(=配布したセッションIDを参照して、セットになっているデータを呼び出す)ことができます。

 

透過機能は少し別の話になりそうなのと長くなったので次の記事で。