Webサイトを見ていると、よく目にする言葉があります。
Cookie(クッキー)
「Cookieを許可してください」
「Cookieを使用しています」
という表示を見たことがある人も多いでしょう。
でもPHPを書いていると、今度はこんなコードが登場します。
setcookie('name', '山田太郎');
そして、
$_COOKIE['name']
……Cookieって、あの「同意する・しない」のCookie?
前回勉強した$_SESSIONとは何が違う?
今回は、そんなCookieの正体を、
「ブラウザに情報を保存する仕組み」
というところから見ていきます。
事件発生:「次回来たときも覚えておいて!」
こんなWebページがあったとします。
利用者が表示テーマを、
ライトモード
から、
ダークモード
へ変更しました。
別のページへ移動しても、
ダークモードのままにしたい。
さらに翌日、同じサイトへ戻ってきたときも、
前回選んだ設定を覚えていてほしい。
こういうとき、
「このブラウザでは前回、何を選んだ?」
という情報を保存しておけると便利です。
そこで使われる仕組みのひとつが、
Cookieです。
Cookieはブラウザ側に保存される小さな情報
ものすごく簡単にすると、Cookieは、
Webサイトがブラウザ側に保存させる小さな情報
です。
たとえば、
theme = dark
という情報をCookieとして保存したとします。
すると次回アクセスしたとき、
このブラウザは
theme = dark
だった
という情報をWebサイト側で利用できます。
イメージとしては、
Webサイト
↓
「この情報を覚えておいて」
ブラウザ
┌────────────┐
│ theme = dark │
└────────────┘
↓ 次回アクセス
Webサイト
↑
「前回darkだったよ」
という感じです。
PHPでCookieを保存してみる
PHPでは、
setcookie('theme', 'dark');
のようなコードを見ることがあります。
setcookie()という名前からも分かるように、
Cookieを設定するための関数
です。
ここでは、
theme
という名前で、
dark
という値を保存しようとしています。
つまり、
setcookie('theme', 'dark');
を見たら、
「ブラウザへthemeというCookieを設定しているんだな」
と読めれば、まずは十分です。
保存したCookieはどうやって読む?
今度は、
$_COOKIE
が登場します。
たとえば、
echo $_COOKIE['theme'];
とすれば、送られてきたCookieのthemeという値を取得できます。
もし、
theme = dark
なら、
dark
を取得できます。
ここで見覚えのある形になりました。
$_GET
$_POST
$_SESSION
$_COOKIE
全部、
$_○○
という形ですね。
今まで出てきた4つを整理しよう
ここで一度まとめてみましょう。
| PHP | 主な役割 |
|---|---|
$_GET | URLなどから送られてきた値を受け取る |
$_POST | POSTで送信された値を受け取る |
$_SESSION | セッションに保存された値を扱う |
$_COOKIE | ブラウザから送られてきたCookieを扱う |
細かい例外や仕組みはありますが、初心者の段階ではこの違いが見えれば十分です。
AIが、
$_COOKIE['theme']
と書いてきたら、
「ブラウザ側に保存されたthemeという情報を見ているんだな」
と推測できます。
SESSIONとCookie、何が違うの?
ここが今回、一番混乱しやすいところです。
前回の$_SESSIONも、
ページを移動しても情報を持っておける
仕組みでした。
Cookieも情報を覚えています。
では何が違うのでしょう。
大きな違いのひとつは、
情報をどこで保持するか
です。
一般的なPHPセッションでは、
SESSION
↓
データ本体は主にサーバー側
Cookieでは、
Cookie
↓
ブラウザ側
に情報を保存します。
ただし、SESSIONとCookieは完全に無関係ではありません。
SESSIONでもCookieを使っている?
前回少しだけ触れました。
PHPの一般的なセッションでは、ブラウザ側に、
「私はこのセッションですよ」
と識別するためのIDを持たせます。
そのIDの受け渡しにCookieが使われることがあります。
イメージとしては、
ブラウザ
┌────────────────┐
│ セッションID:ABC123 │
└────────────────┘
↓
サーバー
↓
「ABC123なら、このセッションだ」
つまり、
SESSIONとCookieは対立する仕組みではありません。
セッションを成立させるためにCookieが利用されることもあります。
Cookieにパスワードを入れていい?
ここは重要です。
Cookieはブラウザ側に保存される情報です。
だから、
setcookie('password', 'mypassword123');
のように、
重要な情報をそのままCookieへ保存する
という発想は避けましょう。
Cookieは利用者側から確認・変更される可能性があります。
そのため、
Cookieに
is_admin = 1と保存して、1なら管理者!
のように、Cookieの値だけを信用して重要な権限を決める設計も危険です。
初心者の段階では、
Cookieに入っている値を「絶対に正しい」と信用しない
と覚えておくとよいでしょう。
「ログイン状態を保存する」はもう少し複雑
Webサイトには、
ログイン状態を保持する
次回から自動ログイン
といった機能があります。
これを見ると、
CookieにユーザーIDとパスワードを入れればいいのでは?
と思うかもしれません。
実際の安全なログイン保持は、そんなに単純ではありません。
推測されにくいトークンを発行したり、サーバー側でも検証できるようにしたり、有効期限を設けたりといった設計が必要になります。
ここでは、
「ログインを保持したい=パスワードをCookieに保存」ではない
ということだけ覚えておきましょう。
Cookieには有効期限を設定できる
Cookieの特徴のひとつが、
有効期限を設定できること
です。
たとえばPHPでは、考え方として、
setcookie('theme', 'dark', time() + 60 * 60 * 24 * 30);
のようなコードを見ることがあります。
後ろの部分は、
現在時刻
+
60秒
× 60分
× 24時間
× 30日
なので、およそ30日後を表しています。
つまり、
「このCookieを30日程度保持する」
という指定です。
今は計算式を覚えなくても大丈夫です。
setcookie()には、
いつまで保存するかを指定できる
という点を押さえておきましょう。
有効期限がないCookieもある
Cookieは必ず何ヶ月も残るわけではありません。
設定によっては、ブラウザのセッションが終了するまで利用されるCookieもあります。
つまり、
Cookie=永久保存
ではありません。
何を、どのくらい保存するのかは、Cookieを設定する側の設計によって変わります。
Cookieを削除したいときは?
Cookieには「削除ボタン」のようなPHP関数があると思うかもしれません。
実際には、過去の時刻を有効期限として指定するような方法でCookieを無効化するコードを見かけます。
たとえば、
setcookie('theme', '', time() - 3600);
のような形です。
細かい書き方より、
Cookieは設定するだけでなく、期限を使って消すこともできる
と理解しておけば十分です。
事件発生:setcookie()したのに$_COOKIEにない!
ここはPHP初心者がハマりやすいところです。
こんなコードを書きました。
setcookie('theme', 'dark');
echo $_COOKIE['theme'];
「今darkを保存したんだから、すぐ表示されるよね?」
と思います。
ところが、期待どおりにならないことがあります。
なぜでしょう。
Cookieはブラウザとのやり取り
setcookie()は、ざっくり言えば、
「このCookieをブラウザに設定してください」
という情報をレスポンスで送ります。
ブラウザがそれを保存し、その後のリクエストでCookieをサーバーへ送ってきます。
つまり、
PHP
↓
setcookie()
↓
ブラウザへ送る
↓
ブラウザが保存
↓
次のリクエスト
↓
CookieがPHPへ送られる
という流れがあります。
だから、
setcookie()した瞬間に、同じリクエストの$_COOKIEが自動で書き換わる
と考えると混乱します。
ここでも「ページの流れ」を見る
前回のSESSIONでも、
login.php
↓
mypage.php
というページの流れを見ることが重要でした。
Cookieも同じです。
PHP
↓
ブラウザ
↓
次のアクセス
↓
PHP
という、
ブラウザとの往復
を考えます。
Webプログラムでは、
コードの上から下だけを見ても分からない
ことが少しずつ増えてきます。
setcookie()にも「headers already sent」が出ることがある
前回、
session_start();
で、
headers already sent
というエラーが出る場合があると紹介しました。
setcookie()でも似た問題に遭遇することがあります。
CookieはHTTPヘッダーを使ってブラウザへ送られるためです。
そのため、
<h1>こんにちは</h1>
<?php
setcookie('theme', 'dark');
?>
のように、先に出力してからCookieを設定しようとすると問題になる場合があります。
基本的には、
<?php
setcookie('theme', 'dark');
?>
<h1>こんにちは</h1>
のように、
HTMLなどを出力する前に処理する
形をよく見かけます。
SESSIONの記事がここでつながった
前回、
session_start();
でheaders already sentが出ることがある、と説明しました。
今回、
setcookie();
でも同じ言葉が出てきました。
これは偶然ではありません。
どちらも、
ブラウザへ送るHTTPヘッダーと関係する処理
だからです。
こうして過去の記事の知識がつながってくると、
初めて見るエラーでも、
あれ?
これ前にも見たぞ。
となります。
それがかなり重要です。
Cookie同意バナーは何なの?
ここでようやく、
「Cookieを許可しますか?」
という表示の話です。
Cookieには、サイトを動かすために使われるものだけでなく、アクセス解析や広告などに関係するものもあります。
そのため、サイトの用途や利用するサービス、対象地域などによっては、Cookieなどの利用について利用者への説明や同意取得が必要になる場合があります。
ただし、
Cookieそのもの=Cookie同意バナー
ではありません。
CookieはWebで情報を保持する仕組み。
同意バナーは、その利用について利用者へ説明したり選択してもらったりするための仕組みです。
まずは分けて考えましょう。
ブラウザの開発者ツールでも確認できる
Cookieはブラウザ側に保存されるので、Chromeなどの開発者ツールから確認できる場合があります。
「Application」などの項目を見ると、
Cookies
という項目があります。
そこでは、
どんなCookieが保存されている?
名前は?
値は?
有効期限は?
などを確認できます。
PHPコードだけでなく、
ブラウザ側で実際に何が起きているかを見る
ことも、トラブル調査では役立ちます。
AIに聞くときもCookieの流れを伝える
たとえば、
Cookieが動きません。
だけではなく、
login.phpでsetcookie()しています。
その後mypage.phpへ移動し、$_COOKIEを確認しています。
と伝えます。
さらに、
setcookie('theme', 'dark');
というコードと、
login.php
↓
mypage.php
というページの流れも見せる。
AIにコードを書いてもらう時代でも、
「何が起きているのか説明できる人」
のほうが、問題を解決しやすくなります。
SESSIONとCookieを最後に整理
今回のポイントを簡単に並べます。
SESSION
主なデータ:サーバー側
用途:一連のアクセスで状態を持つ
例:ログイン状態など
Cookie
保存:ブラウザ側
用途:ブラウザに小さな情報を保持する
例:表示設定など
そして、
SESSIONを識別するためにCookieが使われることもある。
この関係が分かれば、かなり十分です。
今日の合格ライン
今回覚えてほしいのは4つです。
1. Cookieはブラウザ側に小さな情報を保存する仕組み。
2. PHPではsetcookie()で設定し、$_COOKIEで送られてきた値を扱える。
3. Cookieに入っている値を無条件に信用しない。
4. SESSIONとCookieは別物だが、関係することもある。
そして、
$_COOKIE['theme']
を見たとき、
「このブラウザから送られてきたCookieを見ているんだな」
と分かれば、今日の合格ラインです。
ワンポイント答え合わせ
PHPで、
setcookie('theme', 'dark');
を実行しました。
これは何をしようとしているでしょう?
A:PHPの普通の変数にdarkを入れている
B:ブラウザへtheme=darkというCookieを設定するよう送ろうとしている
答えは、
Bです。
Cookieを理解すると、
PHPだけ
ではなく、
PHP
↓
ブラウザ
↓
PHP
というWebの往復が見えてきます。
そしてここまで来ると、
$_GET
$_POST
$_SESSION
$_COOKIE
が、それぞれ何のために存在しているのかも少しずつ整理できるようになります。
コードを全部覚える必要はありません。
「この値は、どこから来た?」
それを考えられるだけでも、AIが作ったPHPを調査する力は大きく変わります。
