クッキーを送信する

# setcookie

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

setcookie — クッキーを送信する

### 説明

function 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 以降で使える代替のシグネチャ(名前付き引数をサポートしていません):

function 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)です。 値については、キーと同じ名前のパラメーターで説明した意味と同じです。 `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_start() や ob_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() を複数回コールした場合は、コールした順番で実行されます。

### 参考

- header() - 生の HTTP ヘッダを送信する
- setrawcookie() - 値を URL エンコードせずにクッキーを送信する
- クッキー
- » RFC 6265
- » RFC 2109

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open