【PHP実践】Cookies¶

概要

HTTPクッキーは、Webサイトがユーザーに関する情報を保存するために使用する、小さなテキストファイルです。ブラウザに保存され、次回同じサイトにアクセスした際に、サーバーに送信されます。これにより、セッション管理、パーソナライゼーション、トラッキングなどが可能になります。PHPでは、`setcookie()` 関数を使用してクッキーを設定し、`$_COOKIE` スーパーグローバル配列を介してクッキーの値を取得します。クッキーは、ユーザーエクスペリエンスの向上に不可欠な技術ですが、プライバシーやセキュリティに関する考慮事項も存在します。本記事では、PHPにおけるクッキーの基本的な使い方から、より実践的な応用、そして注意点までを詳細に解説します。

詳細解説

クッキーの仕組み

HTTPはステートレスなプロトコルであり、サーバーは各リクエストを独立したものとして扱います。つまり、以前のリクエストで送信された情報が、次のリクエストで自動的に利用できるわけではありません。この問題を解決するために、クッキーが導入されました。

クッキーの基本的な流れは以下のようになります。

1. **サーバーからのクッキー設定:** ユーザーがWebサイトにアクセスすると、サーバーはHTTPレスポンスヘッダーに `Set-Cookie` ディレクティブを含めて、ブラウザにクッキーを設定するように指示します。このディレクティブには、クッキーの名前、値、有効期限、ドメイン、パス、セキュリティフラグなどが含まれます。
2. **ブラウザによるクッキー保存:** ブラウザは、サーバーから受け取った `Set-Cookie` ヘッダーの内容を解釈し、指定されたクッキーをローカルストレージに保存します。
3. **ブラウザからのクッキー送信:** ユーザーが再度同じWebサイトにアクセスすると、ブラウザは保存されているクッキーの中から、該当するサイト(ドメインとパスが一致するもの)のクッキーをHTTPリクエストヘッダーの `Cookie` フィールドに含めてサーバーに送信します。
4. **サーバーによるクッキーの利用:** サーバーはリクエストヘッダーに含まれるクッキーを受け取り、それを利用してユーザーを識別したり、以前の状態を復元したりします。

PHPでのクッキー設定: `setcookie()` 関数

PHPでクッキーを設定するには、`setcookie()` 関数を使用します。この関数は、HTTPレスポンスヘッダーを送信する前に呼び出す必要があります。通常、PHPスクリプトの冒頭で実行されます。

`setcookie()` 関数の基本的な構文は以下の通りです。

setcookie(name, value, expire, path, domain, secure, httponly);

各引数の意味は以下の通りです。

* `name`: クッキーの名前(必須)。
* `value`: クッキーの値(必須)。
* `expire`: クッキーの有効期限。Unixタイムスタンプで指定します。指定しない場合、ブラウザのセッション終了時にクッキーは削除されます(セッションクッキー)。
* `path`: クッキーが有効なサーバー上のパス。`/` を指定すると、サイト全体で有効になります。デフォルトは現在のディレクトリです。
* `domain`: クッキーが有効なドメイン。`.example.com` のように指定すると、サブドメインでも有効になります。デフォルトは現在のホスト名です。
* `secure`: `true` に設定すると、HTTPS接続時のみクッキーが送信されます。
* `httponly`: `true` に設定すると、JavaScriptなどのクライアントサイドスクリプトからクッキーにアクセスできなくなります。XSS攻撃によるクッキーの盗難を防ぐのに役立ちます。

**例:**


“;
echo “値: ” . $_COOKIE[$cookie_name];
}
?>

この例では、`username` という名前で `JohnDoe` という値を、1時間有効なクッキーとして設定しています。`path` に `/` を指定しているため、サイト全体でこのクッキーが有効になります。

PHPでのクッキー取得: `$_COOKIE` スーパーグローバル配列

設定されたクッキーの値は、PHPの `$_COOKIE` スーパーグローバル配列を介して取得できます。この配列のキーはクッキーの名前、値はクッキーの値です。

**例:**

`$_COOKIE` 配列は、リクエスト時にブラウザから送信されたクッキーのみを含みます。`setcookie()` 関数で設定したクッキーであっても、そのクッキーがブラウザによって送信されるのは、**次のリクエストから**となります。そのため、`setcookie()` を呼び出した直後のスクリプト内では、そのクッキーの値は `$_COOKIE` には含まれていません。

クッキーの削除

クッキーを削除するには、有効期限を過去の日付に設定して `setcookie()` 関数を再度呼び出します。

**例:**



クッキーの値を空文字列にすることも、削除の際に一般的に行われます。

クッキーの属性とセキュリティ

* **`secure` 属性:** `true` に設定すると、クッキーはHTTPS接続時のみ送信されます。機密性の高い情報を扱う場合は、必ず `true` に設定してください。
* **`httponly` 属性:** `true` に設定すると、JavaScriptからクッキーへのアクセスが制限されます。これにより、クロスサイトスクリプティング(XSS)攻撃でクッキーが盗まれるリスクを軽減できます。重要なクッキーには `httponly` を有効にすることを強く推奨します。
* **`domain` 属性:** 特定のドメインにのみクッキーを有効にしたい場合に設定します。`www.example.com` と `sub.example.com` の両方でクッキーを共有したい場合は、`.example.com` のようにドメイン名の前にドットを付けて設定します。
* **`path` 属性:** クッキーが有効なパスを指定します。`/` を指定すると、サイト全体で有効になります。特定のディレクトリ以下でのみクッキーを有効にしたい場合に便利です。

クッキーの利用例

* **セッション管理:** ログイン状態を維持するために、セッションIDをクッキーに保存することが一般的です。PHPのセッション機能 (`session_start()`) は、デフォルトでセッションIDをクッキーに保存します。
* **パーソナライゼーション:** ユーザーの言語設定、テーマ設定、表示設定などをクッキーに保存し、次回アクセス時に反映させることができます。
* **トラッキング:** ユーザーの行動履歴や閲覧履歴を追跡するために使用されることがあります。ただし、プライバシーへの配慮が必要です。
* **ショッピングカート:** ログインしていないユーザーのショッピングカートの内容を一時的に保存するためにクッキーが利用されることがあります。

クッキーの限界と代替手段

クッキーは便利ですが、いくつかの限界があります。

* **容量制限:** ブラウザごとに保存できるクッキーの総数や、1つのクッキーのサイズには制限があります。
* **セキュリティ:** クッキーはクライアントサイドに保存されるため、改ざんや盗難のリスクがあります。機密性の高い情報はクッキーに直接保存すべきではありません。
* **ユーザーによる無効化:** ユーザーはブラウザの設定でクッキーを無効にすることができます。その場合、クッキーを利用した機能は動作しません。

これらの限界に対処するために、以下の代替手段や補完的な技術が利用されます。

* **Web Storage API (localStorage, sessionStorage):** ブラウザにデータを保存するためのAPIです。クッキーよりも大容量のデータを保存でき、HTTPリクエストヘッダーに自動的に含まれないため、パフォーマンスへの影響が少ないです。
* `localStorage`: ブラウザを閉じてもデータが永続します。
* `sessionStorage`: ブラウザを閉じるとデータが削除されます。
* **サーバーサイドセッション:** セッションIDのみをクッキーに保存し、実際のセッションデータはサーバー側のデータベースやファイルに保存する方法です。機密性の高い情報を扱う場合に推奨されます。PHPの標準セッション機能がこれにあたります。

サンプルコード

クッキーの設定と取得(ログイン状態の維持)

この例では、ユーザーがログインボタンをクリックした際に、ユーザー名をクッキーに保存し、次回アクセス時に「ようこそ、[ユーザー名]さん」と表示します。



クッキーを使ったログイン例

クッキーを使ったログイン例

ようこそ、さん!

ログアウト

ユーザー名:

このページは、クッキーにユーザー名が保存されている場合、それを表示します。
クッキーはブラウザを閉じても保存されます(1日間有効)。



ログアウト

ログアウトしました

ログインページに戻る

パーソナライゼーション(言語設定)

ユーザーが言語を選択し、その選択をクッキーに保存して、次回アクセス時に反映させる例です。

‘日本語’, ‘en’ => ‘English’];
$default_language = ‘ja’;
$language = $default_language;

// クッキーから言語設定を取得
if (isset($_COOKIE[‘user_language’])) {
$language = $_COOKIE[‘user_language’];
}

// 言語が変更された場合
if ($_SERVER[“REQUEST_METHOD”] == “POST” && isset($_POST[‘language’])) {
$new_language = $_POST[‘language’];
if (array_key_exists($new_language, $supported_languages)) {
$language = $new_language;
// 言語設定をクッキーに保存(1年間有効)
setcookie(‘user_language’, $language, time() + (60 * 60 * 24 * 365), “/”);
}
}

// 言語に応じたテキストを取得
$texts = [
‘ja’ => [
‘title’ => ‘言語設定’,
‘current_language’ => ‘現在の言語: ‘,
‘select_language’ => ‘言語を選択:’,
‘submit_button’ => ‘設定を保存’,
‘greeting’ => ‘こんにちは!’
],
‘en’ => [
‘title’ => ‘Language Settings’,
‘current_language’ => ‘Current Language: ‘,
‘select_language’ => ‘Select Language:’,
‘submit_button’ => ‘Save Settings’,
‘greeting’ => ‘Hello!’
]
];

// 現在の言語設定のテキストを取得
$current_texts = $texts[$language];
?>


<?php echo $current_texts['title']; ?>



このページは、クッキーに保存された言語設定に基づいて表示されています。

この例では、`

タイトルとURLをコピーしました