setcookie

クッキーを送信する

説明

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

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

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

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)です。 値については、キーと同じ名前のパラメーターで説明した意味と同じです。 samesite 要素の値は、 None, Lax または Strict です。 上記で許されているオプションのうち、与えられなかったものについては、 デフォルト値は明示的にパラメータを与えた場合のデフォルト値と同じです。 samesite 要素が省略された場合は、SameSite クッキー属性は設定されません。

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

注意: samesite"None" に設定する場合、secure も有効にしなければなりません。 さもないと、クッキーがクライアントにブロックされてしまいます。

戻り値

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

エラー / 例外

options 配列にサポートされていないキーが含まれている場合:

  • PHP 8.0.0 より前のバージョンでは、E_WARNING が発生していました。
  • PHP 8.0.0 以降では、ValueError がスローされます。

変更履歴

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

The effects of the following examples can be observed using the browser developer tools cookie list (usually in the Storage or Application tab).

例1 setcookie でクッキーを送信する例

<?php

$value = 'something from somewhere';

// Set a "session cookie" that expires when the browser is closed
setcookie("TestCookie", $value);
// Set a cookie that expires in 1 hour
setcookie("TestCookie", $value, time()+3600);
// Set a cookie that applies only to a specific path on a specific domain
// Note that the domain used should match the site domain
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", true);

?>

クッキーの value の部分は、クッキーの送信を行う際に自動的に URL エンコードされ、またクッキーを受信した際は、自動的にデコード されることに注意してください。 この挙動は setrawcookie を代わりに使うことでで回避できます。

上の例でセットしたクッキーの内容を、 後続のリクエストで参照するには、以下のようにします:

<?php
// Print an individual cookie
echo $_COOKIE["TestCookie"];

// Another way to debug/test is to view all cookies
print_r($_COOKIE);
?>

例2 setcookie でクッキーを削除する例

クッキーを削除する場合には、ブラウザの削除機構を起動するために 必ず有効期限を過去(但し、0 ではありません。 0はセッションクッキーのために予約されています) に設定する必要があります。

先ほどの例で送信したクッキーを削除する例を以下に示します:

<?php
// set the expiration date to one hour ago
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);
?>

例3 setcookie と配列

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

<?php
// set the cookies
setcookie("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");

// after the page reloads, print them out
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_startob_end_flush を使用するか、 あるいは php.ini やサーバー設定ファイルの output_buffering を使用します。

陥りやすい失敗:

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

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

参考