1. セッションとは何ですか?Webサイトで果たす役割を解説します

Webサイトを閲覧していると、「ログイン状態が維持されている」「ショッピングカートに商品が残っている」といった状態を体験しますよね。この「状態」を一時的に保持するための仕組みが**セッション(Session)**です。

インターネットの基本技術であるHTTP(HyperText Transfer Protocol)は、本来「ステートレス(状態を保持しない)」という性質を持っています。これは、サーバーが一度リクエストに応答すると、その接続をすぐに忘れ、以前の通信内容を覚えていないということです。

💡 初心者へのヒント:ステートレスとは?
コンビニの店員さんを想像してください。あなたが朝におにぎりを買い、昼にまた行っても「あ、朝の人ですね!」とはならず、「いらっしゃいませ(初めまして)」と対応されますよね。これがステートレスです。
しかし、もしあなたが「会員証」を見せれば、「あ、いつもの田中さんですね」と認識されます。この会員証の仕組みがセッションに近いイメージです。

実際のWebサイトでは、ログイン中のユーザーやカート情報など、「状態」を継続的に管理する必要があります。セッションは、このHTTPのステートレス性を補い、一連のユーザーの操作を紐づけて(関連付けて)管理するために不可欠な技術です。特にWEB開発 基礎を学ぶ上で、このセッションの役割の理解は欠かせません。

セッションがWebサイトで果たす主な役割

  • ログイン状態の維持(認証情報の保持): ユーザーがIDとパスワードでログインした後、すべてのページで「この人はログイン済みである」という状態を維持します。
  • ショッピングカート機能: ユーザーが選んだ商品情報や数量を、決済が完了するまでの一時的なデータとして保持します。
  • ユーザーごとの設定保存: サイト内での表示設定や言語設定など、一時的にパーソナライズ(個人化)された情報を保存します。

2. セッションとCookie:決定的な違いと使い分けを理解しよう

セッションとCookieは、どちらも「状態を保持する」ために使われますが、データをどこに保存するかに決定的な違いがあります。この違いを理解することで、より安全で効率的なPHP Web開発が可能になります。

決定的な違いは「データの保存場所」

項目セッション(Session)Cookie(クッキー)
主な保存場所サーバー側(Webサーバーのファイルやデータベース)クライアント側(ユーザーのWebブラウザ)
データの中身任意の複雑なデータ(ログインID、カート情報など)サーバーが発行したセッションIDが主(その他、簡易な情報)
セキュリティサーバー側で管理されるため、比較的安全ユーザーによって容易に閲覧・改ざんが可能で、セキュリティリスクが高い
容量制限サーバー側のリソースが許す限り、ほぼ制限なし比較的厳しい制限がある(一般的に4KBまで)

🔑 コインロッカーで例えると?

  • セッション(ロッカーの中身): 荷物(データ)そのものは駅のロッカー(サーバー)の中に安全に保管されています。
  • Cookie(ロッカーの鍵): ユーザーは「ロッカー番号が書かれた鍵(セッションID)」だけを持っています。鍵自体には荷物は入っていませんが、これを使うことで自分の荷物を取り出せます。

セッションとCookieの使い分けのポイント

  • セッションを使うべきケース: 機密性の高い情報、セキュリティが求められる場合に使用します。
    • 例: ログイン中のユーザー認証情報、決済前のカート内容、個人情報を含むデータ。
  • Cookieを使うべきケース: 比較的単純で、機密性の高くない情報をユーザーのブラウザ側で長期的に保持したい場合に使用します。
    • 例: 「次回から自動ログイン」のためのトークン、以前閲覧した商品履歴、サイトのテーマカラー設定(ダークモードなど)。

3. セッションの仕組み:データはどこに保存され、どう管理されるのですか?

セッションの仕組みは、ブラウザとサーバーの間で「セッションID」という一意の鍵をやり取りすることで成り立っています。このセッションIDこそが、サーバー側で保存されている膨大なユーザーデータの中から、特定のユーザーの情報を特定するための目印となるのです。

セッションが開始されてから終了するまでの流れ

  1. セッションの開始(サーバー側): ユーザーがWebサイトにアクセスし、セッションが必要な処理(例: ログイン)を行うと、サーバーはセッションIDと呼ばれるランダムな文字列を生成します。
  2. セッションデータの保存(サーバー側): サーバーは、生成したセッションIDをキー(識別子)として、ユーザーのデータ(例: ユーザーID)をセッションファイルやデータベースに保存します。
  3. セッションIDの発行(クライアント側へ): サーバーは生成したセッションIDをCookieとしてユーザーのWebブラウザに送信します。
  4. データ取得時の連携(ブラウザ→サーバー): ユーザーが別のページに遷移する際、ブラウザは保存しているセッションID(Cookie)をリクエストに含めて自動的にサーバーへ送信します。
  5. データの照合と利用(サーバー側): サーバーはこの受け取ったセッションIDを使って、セッションファイルから対応するユーザーのデータを特定し、処理に利用します。

セッションデータが保存される場所

PHPのセッションの仕組みでは、標準設定だとWebサーバー内の一時的なファイル(セッションファイル)として保存されます。この保存場所は php.inisession.save_path という設定項目で確認・変更が可能です。大規模なサイトでは、高速なデータ処理のためにRedisなどのインメモリデータベースに保存することもあります。

4. PHPでセッションを利用するための基本的な手順と設定方法

WEB開発で最も利用頻度の高い言語の一つであるPHPでは、セッションを非常に簡単に扱うことができます。ただし、セッションを利用するためには、データの読み書きを行うどの処理よりも前session_start() 関数を呼び出す必要があります。これがPHPでセッションを利用する上での基本手順となります。

session_start() 関数はすべてのセッション操作の前に必須

session_start() 関数は、PHPがセッションIDの送受信やサーバー側のセッションファイルからのデータ読み込みといった初期準備を行うために必要な「おまじない」です。

【重要】 session_start() は、HTMLタグや空白文字を含むいかなる出力よりも前に実行しなければなりません。もし出力後に実行しようとすると、「Headers already sent」といったエラーが発生し、セッションIDをブラウザに送信できなくなります。

<?php
// ⭕️ 正しい書き方:HTMLなどの出力の前に書く
session_start(); 
?>

<!DOCTYPE html>
<html>
<head>...</head>
<body>...</body>
</html>

セッションに関する主要なphp.ini設定

PHP セッション 使い方に関連する主要な設定は、Webサーバー全体の設定ファイルである php.ini で管理されています。通常、レンタルサーバーなどではデフォルトのままで問題なく動作しますが、知識として知っておきましょう。

  1. session.save_path: セッションデータを保存するサーバー上のディレクトリ(フォルダ)を指定します。
  2. session.name: セッションIDを格納するCookieの名前を指定します。デフォルトの PHPSESSID から変更することがセキュリティ上推奨される場合もあります。

5. セッションへのデータ登録・取得・削除の具体的なコード例

PHPでは、セッションデータは $_SESSION という特別なスーパーグローバル変数(PHPスクリプトのどこからでもアクセスできる変数)を配列として使って操作します。

データの登録(書き込み)・更新

$_SESSION 変数に、キー(識別用の名前)と値を指定して代入することで、データをセッションに登録(保存)できます。

<?php
session_start();

// 'username' というキーで 'Taro' を保存
$_SESSION['username'] = 'Taro';

// 'cart_items' というキーで数を保存
$_SESSION['cart_items'] = 3;

echo 'セッションにデータを保存しました。';
?>

データの取得(読み込み)

登録時と同じキーを使って値を取り出します。キーが存在しない場合にエラーにならないよう、isset() 関数(変数がセットされているかを確認する関数)でチェックすることが一般的です。

<?php
session_start();

// データが保存されているか確認してから表示
if (isset($_SESSION['username'])) {
    echo 'ようこそ、' . $_SESSION['username'] . 'さん!';
} else {
    echo 'ログインしていません。';
}
?>

セッションデータの削除(特定データ・全データ)

セッションデータには、特定の値だけを消す方法と、セッション全体を破棄する方法があります。

  1. 特定キーの削除 (unset): unset() 関数を使って、$_SESSION 配列の中から特定のキーだけを削除します。
  2. セッション全体の破棄 (session_destroy): ユーザーのログアウト時などに、セッション全体をサーバー側から破棄し、セッションIDも無効にします。
<?php
session_start();

// 1. 特定のデータだけ消す場合(例:カートの中身だけ空にする)
unset($_SESSION['cart_items']);

// 2. ログアウト時など、完全にセッションを消す手順
$_SESSION = array(); // メモリ上のセッション変数を空にする
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), '', time() - 42000, '/'); // Cookieも削除
}
session_destroy(); // サーバー側のセッションファイルを破壊

echo 'ログアウトしました。';
?>

6. セッションが切れる(タイムアウト)原因と時間を変更する方法

セッションにはセキュリティ上の理由から必ず有効期限が設けられています。この有効期限が過ぎる、または特定の原因によってセッションIDが失効すると、セッションが切れ(タイムアウトし)、再度ログインが必要な状態になります。

セッションタイムアウトの主な原因

セッションのタイムアウトは、主にサーバー側のセッション有効期限クライアント側のCookieの有効期限の2つが関係しています。

  1. サーバー側の有効期限切れ: サーバーに保存されているセッションデータが、一定時間アクセスがない場合に自動で削除される(ガベージコレクション)ことによるものです。
  2. セッションCookieの有効期限切れ: セッションIDをブラウザに保存しているCookieが有効期限切れになったり、ブラウザが閉じられたりすることで、サーバーへセッションIDを送れなくなることによるものです。

セッションの有効期限を変更する方法

PHP セッション タイムアウトを変更する方法として、サーバー側の設定(php.ini)を調整します。

; php.ini の設定例

; 1. サーバー側の保存期間(秒)
; デフォルトは1440秒(24分)。例えば1日にしたい場合:
session.gc_maxlifetime = 86400 

; 2. クッキーの有効期限
; 0だとブラウザを閉じると終了。1日残したい場合:
session.cookie_lifetime = 86400

7. セッションを使う際のセキュリティ対策と注意点

セッションIDが漏洩すると、セッションハイジャックなどの深刻なセキュリティ攻撃に利用されてしまう危険性があります。安全なWebサイトを構築するために、必須のセキュリティ対策を理解しましょう。

セッションハイジャック対策:セッションIDの漏洩を防ぐ

セッションハイジャックとは、攻撃者がなんらかの方法で正当なユーザーのセッションIDを盗み出し、そのユーザーになりすましてサービスを利用する行為です。

  • Cookieに HttpOnly 属性を設定する(必須)
    HttpOnly 属性を設定すると、JavaScriptからCookie(セッションID)にアクセスすることを禁止できます。これにより、XSS(クロスサイトスクリプティング)攻撃によってセッションIDが盗まれるのを防げます。
    設定方法:php.inisession.cookie_httponly1 にします。
  • Cookieに Secure 属性を設定する(HTTPS環境で必須)
    Secure 属性を設定すると、SSL/TLS(HTTPS)接続の場合にのみCookieが送信されるようになります。これにより、通信途中でセッションIDが盗聴されるリスクを大幅に減らせます。
    設定方法:php.inisession.cookie_secure1 にします。

セッション固定化対策:ログイン後に必ずセッションIDを再生成する

セッション固定化とは、攻撃者がユーザーに特定のセッションIDを使わせることで、その後のログイン時にそのセッションIDを盗み出す攻撃です。

  • ログイン完了後に session_regenerate_id(true) を実行する(必須)
    ユーザーが認証(ログイン)を完了した直後に、セッションIDを新しいものに再生成することで、以前使われていたセッションIDを無効化できます。
<?php
session_start();

// ... ユーザーIDとパスワードのチェック処理 ...

if ($login_success) {
    // 【重要】ログイン成功直後にセッションIDを新しく振り直す!
    // trueを指定すると、古いセッションファイルを削除します
    session_regenerate_id(true);
    
    $_SESSION['user_id'] = $user_id;
    echo 'ログインしました。';
}
?>