PHP - WEB - 12. セッションの詳細
引き続きセッションについて学習していきましょう。Webアプリケーションにおいてユーザとの一連のやりとりの間で発生するデータを保存するにはセッションという仕組みを使います。PHPにおいて、セッションを利用するためには予め session_start 関数を呼び出した後、 $_SESSION 変数にアクセスします。それでは、このときWebブラウザとWebサーバ間のHTTP通信ではどのようなデータのやりとりが行われているのでしょうか。ここでは具体的なHTTP通信のやりとりを中心に見ていくことにします。
Cookie
一般的にセッションはその内部でCookieという仕組みを使います。CookieとはHTTPのクライアント(Webブラウザ)上に少量のデータを保存する仕組みです。もともとHTTPの通信ではWebサーバからWebブラウザ上のコンピュータに対してファイルを作成したり、削除したりといった操作は禁止されています。これを許可してしまうとWebサーバから、Webブラウザを使っている利用者のコンピュータを自由に操作できてしまうためです。そのような背景においてCookieはWebサーバからWebブラウザ上にデータを残すことのできる例外的な仕組みです。

CookieはPHPの連想配列のようにキーと値の組み合わせでデータを管理します。ただし、 Cookieには様々な制約があります。たとえば1つのキーに指定可能な値には少量のデータ(数KB程度)しか保存できないようになっています。
Cookieへのデータの保存
WebサーバからWebブラウザ上のCookieにデータを保存するためにはHTTPレスポンスに set-cookie ヘッダを付与します。具体的には次のようなヘッダフィールドです。
set-cookie: Key1=Value1; path=/
レスポンスの中に上記のような set-cookie ヘッダが存在する場合、Webブラウザは Cookieに Key1 というキーと Value1 という値のペアを保存します。
Cookie上のデータの送信
Cookieに保存されたデータは、Cookieを作成した同一ドメインへのリクエスト時に、自動的にリクエストのヘッダフィールド( Cookie ヘッダ)に含まれるようになります。
Cookie: Key1=Value1
あるドメインによってCookieに保存されたデータは、別のドメインへのリクエストに含まれることはありません。
ドメインとは
https://example.com/におけるexample.com/の部分を指します。example.com/で作成されたCookieデータは同一ドメインへのリクエストにのみ含まれます。別のドメイン(たとえばhttps://example.co.jpなど)へのリクエストに含まれることはありません。
Cookieデータの削除
これからChromeを使ってセッションおよびCookieの動作を確認します。結果をわかりやすく表示するために、ここではChrome上の既存のCookieを削除しておきましょう。
Cookieを削除するにはデベロッパーツールを起動して「Application」タブを選択します。サイドバーに「Cookies」というセクションがあるので、現在アクセスしているドメインを選択します。中央のパネルで Cookieに保存されている項目の一覧が表示されるので PHPSESSID という項目があれば削除しておいてください。

PHPSESSIDとはをPHPのセッションIDを意味します。WebブラウザとWebサーバ間でこのセッションID(PHPSESSID)を使ってセッションを管理します。
PHPプログラムの開発(セッションの仕組み)
ここではさきほどのログイン処理でのやりとりをもとに、実際にどのようなデータ通信が発生してCookieへのアクセスが発生するのかを確認してみましょう。
ビルトインWebサーバを起動した状態で、Webブラウザからログイン画面( login.html )にアクセスします。
https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/login.html
ログイン画面が表示されるのでデベロッパーツール(Networkタブ)を開いた状態でIDに Andy 、パスワードに secret と入力してログインボタンをクリックしましょう。そうするとログイン処理( login.php )へのHTTP通信と、リダイレクト後のメニュー画面表示処理( menu.php )へのHTTP通信2つのキャプチャーが取得できます。

ここではまずログイン処理( login.php )のレスポンスを確認してみましょう。

このレスポンスはメニュー画面表示処理へのリダイレクトを指示しているので、ステータスコードは 302 、また Location ヘッダには遷移先である menu.php が指定されています。このとき Cookie にデータを保存する set-cookie ヘッダが付与されている点に注意してください。
set-cookie: PHPSESSID=atd3ukr5hsc158ggalu2jfe39n; path=/
この set-cookie ヘッダによって、 Cookieに PHPSESSID キーで atd3ukr5hsc158ggalu2jfe39n という値が保存されます。この PHPSESSID という名前のキーはセッションIDと呼ばれるものです。この場合、ユーザのセッションID( PHPSESSID )は atd3ukr5hsc158ggalu2jfe39n となり、Webサーバ上でユーザのセッションを識別する用途に利用します。

セッションを実現するために必要なネットワーク上のやりとりはセッションIDに限定されます。 $_SESSION 変数に保存した "id" や "time" キー、またそれぞれのキーに紐づく値は、セッションIDと関連付けられてサーバサイドに保存されます。
さいごにHTTPレスポンスになぜ、このような set-cookie ヘッダが付与されたのかという疑問が残ります。これはログイン処理( login.php )において session_start 関数を呼び出しているためです。PHPでは session_start 関数を呼び出すことで、セッションの管理に必要なHTTPレスポンス(この場合 set-cookie ヘッダ)を生成するようになっています。
set-cookieヘッダの挙動を上手く動作確認できない場合は、デベロッパーツールの「Application」タブからCookieのPHPSESSIDを削除してから試してください。
以上の結果としてログイン処理( login.php )のレスポンスを受け取ったWebブラウザはCookieに PHPSESSID キーと atd3ukr5hsc158ggalu2jfe39n のような値を保持することになります。

続いてChromeのデベロッパーツール(Networkタブ)から、リダイレクト時のメニュー画面表示処理( menu.php )へのリクエストも確認しておきましょう。

このリクエストはさきほどの set-cookie ヘッダを受信した際のドメインと同一ドメインへのリクエストに該当するので、リクエストには Cookie ヘッダが付与されているのがわかります。
cookie: __Host-previewc9corsvfs_9cUgC45nBy87BGFr=9cwVFQmF9S33Cz2rD813CqUEkhmisxoV; AWSALB=EeucH0/h8tHVca6kUAOIDUfZcVDaXpGLe9BlMDBG6mKUH4luwCot7KveEQq8eEZso9r7Ig9TNPb2w2wTKn4ITJC7jKh3iylAquAxY3cy18D1qw/wC01lONzgx8p/; AWSALBCORS=EeucH0/h8tHVca6kUAOIDUfZcVDaXpGLe9BlMDBG6mKUH4luwCot7KveEQq8eEZso9r7Ig9TNPb2w2wTKn4ITJC7jKh3iylAquAxY3cy18D1qw/wC01lONzgx8p/; PHPSESSID=atd3ukr5hsc158ggalu2jfe39n
Cloud9 は独自でCookieを利用しているためいくつかのパラメータが混在します。さいごの部分に
PHPSESSID=atd3ukr5hsc158ggalu2jfe39nを確認できます。
WebブラウザからWebサーバに送信される cookie ヘッダはPHPプログラムから参照可能です。またサーバ上にはユーザ(セッションID)に紐づくセッション情報が複数存在します。メニュー画面の表示処理( menu.php )において、 session_start 関数を呼び出すことで、このセッション情報の一覧の中から送信されたセッションID( PHPSESSID )に紐づく1件のセッション情報を識別できるようになります。このようにして $_SESSION 変数が利用できるようになります。

まとめ
- 一般的にセッションはCookieを使って実装されている
- Cookieはクライアント(Webブラウザ)上に少量のデータを保存する仕組み
- PHPはセッションを開始するとCookieにセッションIDを保存し、セッションに保存したデータそのものはサーバサイドに保存する