PHPのお勉強!

PHP TOP

setcookie

(PHP 4, PHP 5, PHP 7, PHP 8)

setcookieクッキーを送信する

説明

setcookie(
    string $name,
    string $value = "",
    int $expires_or_options = 0,
    string $path = "",
    string $domain = "",
    bool $secure = false,
    bool $httponly = false
): bool

PHP 7.3.0 以降で使える代替のシグネチャ(名前付き引数をサポートしていません):

setcookie(string $name, string $value = "", array $options = []): bool

setcookie() は、その他のヘッダ情報と共に 送信するクッキーを定義します。 ほかのヘッダ情報と同様に、 クッキーは、スクリプトによる他のあらゆる出力よりも前に 送信される必要があります(これはHTTPプロトコルの制約です)。 <html><head> タグはもちろん 空白も含め、あらゆる出力よりも前にこの関数をコールするようにしなければなりません。

一度クッキーが送信されると、次のページのロードからは $_COOKIE 配列によってクッキーにアクセスできます。 クッキーの値は $_REQUEST 配列からもアクセスできるかもしれません。

パラメータ

setcookie() の各パラメータがどのように作用するのかを知るには » RFC 6265 を参照ください。

name

クッキーの名前。

value

クッキーの値。この値はクライアントのコンピュータに保存されますので、 重要な情報は格納しないでください。 name'cookiename' だとすると、 その値は $_COOKIE['cookiename'] で取得することができます。

expires_or_options

クッキーの有効期限。これは Unix タイムスタンプなので Epoch(1970 年 1 月 1 日)からの経過秒数となります。 この値を設定するひとつの方法として、 time() が返した値に、 期限としたい必要な秒数を加算することが考えられます。 たとえば、time()+60*60*24*30 はクッキーの有効期限を 30 日後にセットします。 別のやり方として、mktime() を使うことも考えられます。 この値に 0 を設定したり省略したりした場合は、 クッキーはセッションの最後(つまりブラウザを閉じるとき) が有効期限となります。

注意:

expires_or_options パラメータには、Wdy, DD-Mon-YYYY HH:MM:SS GMT といった形式ではなく Unix タイムスタンプを渡していることにお気づきでしょうか。 これは、PHP の内部で自動的に変換を行っているからです。

path

サーバー上での、クッキーを有効としたいパス '/' をセットすると、クッキーは domain 配下の全てで有効となります。 '/foo/' をセットすると、クッキーは /foo/ ディレクトリとそのサブディレクトリ配下 (例えば /foo/bar/) で有効となります。 デフォルト値は、クッキーがセットされたときのカレントディレクトリです。

domain

クッキーが有効な (サブ) ドメイン。これを 'www.example.com' などのサブドメインに設定すると、 www サブドメインおよびそれ自身のすべてのサブドメイン (w2.www.example.com など) でクッキーが使えるようになります。 サブドメインを含むドメイン全体でクッキーを有効にしたければ、そのドメイン自体 (この場合は 'example.com') を設定します。

古いブラウザの中には、非推奨になった » RFC 2109 を実装しているものが未だに残っているかもしれません。 そのようなブラウザでは、すべてのサブドメインにマッチさせるためには先頭に . が必要となります。

secure

クライアントからのセキュアな HTTPS 接続の場合にのみクッキーが送信されるようにします。 true を設定すると、セキュアな接続が存在する場合にのみクッキーを設定します。 サーバー側では、このようにセキュアな接続の場合にのみクッキーを送信するという処理は プログラマの責任で行うことになります (たとえば $_SERVER["HTTPS"] の内容を使用します)。

httponly

true を設定すると、HTTP を通してのみクッキーにアクセスできるようになります。 つまり、JavaScript のようなスクリプト言語からはアクセスできなくなるということです。 この設定を使用すると、XSS 攻撃によって ID を盗まれる危険性を減らせる (が、すべてのブラウザがこの設定をサポートしているというわけではありません) と言われていますが、これはしばしば議論の対象となります。 true あるいは false で指定します。

options

expires, path, domain, secure, httponly および samesite のうちから、任意のキーを設定可能な連想配列(array)です。 これら以外のキーが存在する場合、E_WARNING レベルの警告が発生します。 値については、キーと同じ名前のパラメーターで説明した意味と同じです。 samesite 要素の値は、 None, Lax または Strict です。 上記で許されているオプションのうち、与えられなかったものについては、 デフォルト値は明示的にパラメータを与えた場合のデフォルト値と同じです。 samesite 要素が省略された場合は、SameSite クッキー属性は設定されません。

注意:

上のリストにないキーをクッキーの属性に設定する場合、 header() を使います。

戻り値

もしもこの関数をコールする前に何らかの出力がある場合には、 setcookie() は失敗し false を返します。 setcookie() が正常に実行されると、true を返します。 この関数では、ユーザーがクッキーを受け入れたかどうかを判断することはできません。

変更履歴

バージョン 説明
8.2.0 Cookie の日付フォーマットが 'D, d M Y H:i:s \G\M\T' になりました。 これより前のバージョンでは 'D, d-M-Y H:i:s T' でした。
7.3.0 options 配列をサポートする追加のシグネチャが追加されました。 このシグネチャは、SameSite クッキー属性の設定もサポートしています。

以下はクッキーを送信する例です。

例1 setcookie() での送信の例

<?php

$value
= 'something from somewhere';

setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600); /* 有効期限は一時間です */
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", true);

?>

クッキーの value の部分は、クッキーの送信を行う際に自動的に URL エンコードされ、またクッキーを受信した際は、自動的にデコード されてクッキー名と同じ名前の変数に格納されることに注意してください。 この挙動が気に入らない場合、 代わりに setrawcookie() を使ってください。 スクリプト内部で TestCookie の内容を見たい場合は、 以下のいずれかの例を使用します。

<?php
// 個々のクッキーを表示します
echo $_COOKIE["TestCookie"];

// デバッグ/テスト用には、全てのクッキーを見る方法があります。
print_r($_COOKIE);
?>

例2 setcookie() による削除の例

クッキーを削除する場合には、ブラウザの削除機構を起動するために 必ず有効期限を過去に設定する必要があります。 次に、先ほどの例で送信したクッキーを削除する例を示します。

<?php
// 有効期限を一時間前に設定します
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);
?>

例3 setcookie() と配列

クッキー名で配列を記述することにより、クッキーの配列を設定することも可能です。 これにより配列要素と同数のクッキーを設定されますが、 クッキーがスクリプトに受信された際に、 値はクッキー名を有する配列に置きかえられます。

<?php
// クッキーを設定します
setcookie("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");

// ページを再読み込みした後に、表示します
if (isset($_COOKIE['cookie'])) {
foreach (
$_COOKIE['cookie'] as $name => $value) {
$name = htmlspecialchars($name);
$value = htmlspecialchars($value);
echo
"$name : $value <br />\n";
}
}
?>

上の例の出力は以下となります。

three : cookiethree
two : cookietwo
one : cookieone

注意: [] のような区切り文字を Cookie の名前の一部として使ってしまうと、RFC 6265 section 4 違反になります。 しかし、RFC 6265, section 5 によると、 ユーザーエージェントがこうした区切り文字をサポートしていることが想定されています。

注意

注意:

この関数をコールする前でも出力できるように、 スクリプトの全ての出力をサーバー内にバッファリングさせることができます。 そのためには、ob_start()ob_end_flush() を使用するか、あるいは php.ini やサーバー設定ファイルの output_buffering を使用します。

陥りやすい失敗:

  • クッキーは、クッキーを有効にするために次にページをロードするまで アクセスすることができません。クッキーが正常にセットされたか テストするために、クッキーの有効期限が切れる前に次のページを ロードしてクッキーをチェックしてください。 有効期限は expires_or_options 引数でセットされます。 クッキーの利用についてデバッグするのに良い方法は print_r($_COOKIE); をコールすることです。
  • クッキーは設定されたものと同じパラメータで削除する必要があります。 value が空文字列で、その他の全ての引数が前に setcookie() をコールした時と同じである場合に、指定された名前のクッキーが リモートクライアント上から削除されます。 内部的な動作として、これは値を 'deleted' に変更した上で有効期限を 過去に設定しています。
  • クッキーの値として false を設定すると、クッキーを削除しようとします。 そのため、boolean 値は使用できません。その代わりとして、 false ではなく 0、そして true ではなく 1 を使用します。
  • クッキー名で配列を記述することにより、 クッキーの配列を設定することも可能ですが、複数のクッキー がユーザーのシステム上に保存されることになります。 explode() を使用して ひとつのクッキー上に複数の名前と値をセットすることも 考慮してください。serialize() の使用はセキュリティーホールになり得るため、 この目的のために使用することはお勧めしません。

setcookie() を複数回コールした場合は、コールした順番で実行されます。

参考

add a note

User Contributed Notes 12 notes

up
389
walterquez
12 years ago
Instead of this:
<?php setcookie( "TestCookie", $value, time()+(60*60*24*30) ); ?>

You can this:
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
up
267
Bachsau
12 years ago
Want to remove a cookie?

Many people do it the complicated way:
setcookie('name', 'content', time()-3600);

But why do you make it so complicated and risk it not working, when the client's time is wrong? Why fiddle around with time();

Here's the easiest way to unset a cookie:
setcookie('name', 'content', 1);

Thats it.
up
88
Anonymous
4 years ago
Just an example to clarify the use of the array options, especially since Mozilla is going to deprecate / penalise the use of SameSite = none, which is used by default if not using array options.

<?php
$arr_cookie_options
= array (
'expires' => time() + 60*60*24*30,
'path' => '/',
'domain' => '.example.com', // leading dot for compatibility or use subdomain
'secure' => true, // or false
'httponly' => true, // or false
'samesite' => 'None' // None || Lax || Strict
);
setcookie('TestCookie', 'The Cookie Value', $arr_cookie_options);
?>