HOME


PHPのちょっとしたTIPS

Last Modified : 2003/03/18 (Tue)
No.2 クッキーの発行と取得 - setcookie() $HTTP_COOKIE_VARS

setcookie()関数を使用することで容易にクッキーを発行することが出来ます。

<?php

setcookie("クッキー名", "クッキーの値", "有効期限", "パス", "ドメイン名", "セキュア属性");

?>
という感じです。
それぞれの引数の意味は以下のようになります。

引数 意味
クッキー名 クッキーを識別するための任意の名前を指定します。 これは必ず指定しなければなりません。 セミコロン、カンマ、スペース、日本語などのASCII文字以外の文字などを使う時はURLエンコードする必要があります。 しかしこの値は後に変数名になったりするので特殊な文字は使用しない方が無難です。
クッキーの値 クッキー名で指定したクッキーに与える値を指定します。 普通はクッキー名と同様にセミコロン、カンマ、スペースなどを使用する場合はURLエンコードする必要がありますが、 setcookie()関数では、自動的にURLエンコードして送信してくれます。 また、受信時にPHPが自動的にデコードしてくれます。
有効期限 クライアント側でクッキーをいつまで保存しておいて欲しいかをUnixタイムスタンプで指定します。 普通はGMTをRFCで決められフォーマット (Wdy, DD-Mon-YYYY HH:MM:SS GMT) にして指定する必要がありますが、 setcookie()関数ではローカルタイムを自動的に変換してくれます。 この値を省略するとセッション終了(ブラウザを閉じたとき)とともにクッキーは無効になります。 また、過去の日付を指定することで強制的に無効にすることができます。
パス ドメイン名で指定したドメイン中でクッキーを有効にさせるパスを指定します。 省略すると、クッキー発行元のパスが指定されたのと同じ結果になります。
ドメイン名 クライアントにこのクッキーを送信させるドメインを指定します。 省略すると、クッキー発行元のホスト名が指定されたのと同じ結果になります。
セキュア属性 1を指定するとサーバとの接続がセキュア(HTTPS)な場合のみクッキーが送信されます。

通常、パス、ドメイン名、セキュア属性は省略しても差し支えないので、 以下のような使い方が一般的になると思います。
<?php

//有効期限を指定して発行する場合
setcookie("クッキー名", "クッキーの値", "有効期限");

//セッション間でのみ(ブラウザを閉じるまで)有効なクッキーを発行する場合
setcookie("クッキー名", "クッキーの値");

?>
発行したクッキーは次回の訪問から有効になります。
(クライアントからのクッキーはブラウザからのリクエストヘッダ(Cookieヘッダ)に含まれるので当然ですね)
クライアントが送信して来たクッキーは、
<?php

echo $HTTP_COOKIE_VARS["クッキー名"];

?>
という感じで連想配列$HTTP_COOKIE_VARSで取得できます。

またphp.iniでregister_globalsが有効な場合は
$クッキー名
でも取得できます。

setcookie()関数を使用する上でのいくつかの注意点を。
  • 発行されたクッキーはWEBサーバからのレスポンスヘッダ(Set-Cookieヘッダ)に含まれるので、 header()関数と同様にすべての実際の出力の前にコールする必要があります。
  • パスワードなどの重要なデータをクッキーに含ませる場合は特にパスとかドメイン名とかに注意が必要です。 また、ハードディスクに保存されないようにセッション間でのみ有効なクッキーにしてあげた方が良いです。 ブラウザのバージョンによっては、保存してあるクッキーを盗まれるようなバグがあったり、 パソコンをそのまま友達にあげたり中古屋に売ったりする人もいるので。
  • 世の中にはクッキー嫌いな人もいるということを考慮したほうがいいかも。 そしてクッキーの機能を無効にしている人がいることも。

以上を踏まえて、訪問回数を表示する例を。
<?php

/* クッキー名(任意) */
$cookie = "COOKIE_VISIT";

/* クライアントからクッキーが送信されているか判断 */
if (isset($HTTP_COOKIE_VARS[$cookie])) {
    $value = (int)$HTTP_COOKIE_VARS[$cookie];
} else {
    $value = 0;
}

/* 訪問回数のインクリメント */
$value++;

/* 有効期限(1年) */
$expire = time() + 365*24*3600;

/* クッキー発行 */
setcookie($cookie, $value, $expire);

?>
<HTML>
<BODY>
今回で<?php echo $value ?>回目の訪問ですね?
</BODY>
</HTML>
このスクリプトにアクセスすると例えば以下のようなレスポンスが帰ってくるはずです。
(ブラウザでは通常HTTPヘッダは見えませんがtelnetとか使ってアクセスすると確認できます)
$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /cookie.php HTTP/1.0

HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Mon, 18 Jun 2001 02:14:40 GMT
Content-type: text/html
X-Powered-By: PHP/4.0.5
Set-Cookie: COOKIE_VISIT=1; expires=Tue, 18-Jun-02 02:14:40 GMT

<HTML>
<BODY>
今回で1回目の訪問ですね?
</BODY>
</HTML>
Connection closed by foreign host.
setcookie()関数によってHTTPレスポンスヘッダにSet-Cookieヘッダが追加されています。
ちなみにSet-Cookieヘッダの基本フォーマットは、
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
です。
このヘッダを受け取ったブラウザは次回そのURIにアクセスした時にリクエストヘッダにCookieヘッダを含めます。
例えば、
$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /cookie.php HTTP/1.0
Cookie: COOKIE_VISIT=1

HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Mon, 18 Jun 2001 02:56:38 GMT
Content-type: text/html
X-Powered-By: PHP/4.0.5
Set-Cookie: COOKIE_VISIT=2; expires=Tue, 18-Jun-02 02:56:38 GMT

<HTML>
<BODY>
今回で2回目の訪問ですね?
</BODY>
</HTML>
Connection closed by foreign host.
という感じで、
Cookie: クッキー名=クッキーの値
というリクエストヘッダを送信します。 複数のクッキーがある場合は、セミコロン区切りで書きます。
Cookie: 名前1=値1; 名前2=値2; 名前3=値3; ...
というわけでHTTPヘッダのレベルではこんな感じになってます。