update page now

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() を使います。

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

戻り値

もしもこの関数をコールする前に何らかの出力がある場合には、 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 クッキー属性の設定もサポートしています。

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() を複数回コールした場合は、コールした順番で実行されます。

参考

add a note

User Contributed Notes 14 notes

up
397
walterquez
13 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
275
Bachsau
13 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
95
Anonymous
5 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);    
?>
up
24
nacho at casinelli dot com
8 years ago
It's worth a mention: you should avoid dots on cookie names.

<?php
// this will actually set 'ace_fontSize' name:
setcookie( 'ace.fontSize', 18 );
?>
up
36
paul nospam AT nospam sitepoint dot com
19 years ago
Note when setting "array cookies" that a separate cookie is set for each element of the array.

On high traffic sites, this can substantially increase the size of subsequent HTTP requests from clients (including requests for static content on the same domain).

More importantly though, the cookie specification says that browsers need only accept 20 cookies per domain.  This limit is increased to 50 by Firefox, and to 30 by Opera, but IE6 and IE7 enforce the limit of 20 cookie per domain.  Any cookies beyond this limit will either knock out an older cookie or be ignored/rejected by the browser.
up
43
Anonymous
18 years ago
something that wasn't made clear to me here and totally confused me for a while was that domain names must contain at least two dots (.), hence 'localhost' is invalid and the browser will refuse to set the cookie! instead for localhost you should use false.

to make your code work on both localhost and a proper domain, you can do this:

<?php

$domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
setcookie('cookiename', 'data', time()+60*60*24*365, '/', $domain, false);

?>
up
2
ilya at ilya dot top
1 year ago
In any web browser there is a very commonly used option "Open previous windows and tabs" which is disabled by default, but many people enable it.
When this option is active, the web browser, when closing and reopening, instead of executing the termination and starting a new session, saves and restores the current session along with session cookies and sessionStorage.
Both session cookies and sessionStorage, contrary to expectations, can live for a very long time until the user closes the tab before closing the web browser.
If you want a cookie, for example with a time offset, to be guaranteed to have a short lifetime, you should explicitly specify this short lifetime, rather than relying on self-deletion on the session cookie.
up
16
gabe at fijiwebdesign dot com
18 years ago
If you want to delete all cookies on your domain, you may want to use the value of:

<?php $_SERVER['HTTP_COOKIE'] ?>

rather than:

<?php $_COOKIE ?>

to dertermine the cookie names. 
If cookie names are in Array notation, eg: user[username] 
Then PHP will automatically create a corresponding array in $_COOKIE. Instead use $_SERVER['HTTP_COOKIE'] as it mirrors the actual HTTP Request header. 

<?php

// unset cookies
if (isset($_SERVER['HTTP_COOKIE'])) {
    $cookies = explode(';', $_SERVER['HTTP_COOKIE']);
    foreach($cookies as $cookie) {
        $parts = explode('=', $cookie);
        $name = trim($parts[0]);
        setcookie($name, '', time()-1000);
        setcookie($name, '', time()-1000, '/');
    }
}

?>
up
7
synnus at gmail dot com
5 years ago
The " PHPSESSID " cookie will soon be rejected because its " sameSite " attribute is set to " none " or an invalid value, and without " secure " attribute. To learn more about the "sameSite" attribute, visit https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite.

<?php
 ini_set("session.cookie_secure", 1);
 session_start();

my PHP code .... 

?>
up
6
ellert at vankoperen dot nl
11 years ago
Caveat: if you use URL RewriteRules to get stuff like this: domain.com/bla/stuf/etc into parameters, you might run into a hickup when setting cookies.
At least in my setup a change in one of the parameters resulted in the cookie not being 'there' anymore.
The fix is simple: specify the domain. '/' will usualy do fine.
up
3
Anonymous
15 years ago
A period in a cookie name (like user.name) seems to show up in the $_COOKIE array as an underscore (so user_name). This means that for example $_COOKIE["user_name"] must be used to read a cookie that has been set with setcookie("user.name" ...), which is already rather confusing. 

Furthermore the variable $_COOKIE["user_name"] will retain the value set by setcookie("user.name" ...) and no amount of calling setcookie("user_name" ...) will alter this value. This is rather trivially fixed by clearing the "user.name" cookie, but it can take a while to realize this since there's only "user_name" in $_COOKIE.

Hope this saves someone some time.
up
1
alexsvetalena at mail dot ru
6 months ago
Please keep in mind that if you call setcookie() several times during the script execution (even for the same name, domain and path), then Set-Cookie header will be sent several times, and only after receiving all of them, client browser will "merge" them, replacing first value for the cookie with the next etc.

This may cause very large headers length sometimes, so you'll have to either increase buffers for your web server; change your code logic to determine all possibly-changing parameters values right from the start; implement some sort of global Response object keeping all the data, including cookies as well, till the end of processing (sort of optimized output beffering); or just avoid storing any large data in cookies.
up
3
laffen
16 years ago
Note that the $_COOKIE variable not will hold multiple cookies with the same name. It is legitimate to set two cookies with the same name to the same host where the sub domain is different. 
<?php
setcookie("testcookie", "value1hostonly", time(), "/", ".example.com", 0, true);
setcookie("testcookie", "value2subdom", time(), "/", "subdom.example.com", 0, true);
?>
The next request from the browser will have both cookies in the $_SERVER['HTTP_COOKIE'] variable, but only one of them will be found in the $_COOKIE variable. Requests to subdom.example.com will have both cookies, while browser request to example.com or www.example.com only sends the cookie with the "value1hostonly" value.

<?php
$kaker = explode(";", $_SERVER['HTTP_COOKIE']);
foreach($kaker as $val){
    $k = explode("=", $val);
    echo trim($k[0]) . " => " . $k[1];
}

// output
testcookie => value1hostonly
testcookie => value2subdom

?>
up
-1
steven at sovstack dot com
11 months ago
As of PHP 7.3, you can use this syntax:

setcookie( $name,  $value,  $options)

Be aware that the array in $options is not fully compatible with array key names. In other words, the order of your array values matters regardless of the array key names.

<?PHP

// Correct (with key names):
setcookie(
    'my_cookie',
    'my_value',
    [
        'expires' => time() + 3600,
        'path' => '/',
    ]
);

// Correct (without key names):
setcookie(
    'my_cookie',
    'my_value',
    [
        time() + 3600, // expires
        '/' // path
    ]
);

// Incorrect Usage (wrong order as key names are ignored):
setcookie(
    'my_cookie',
    'my_value',
    [
        'path' => '/', // WRONG: should be 2nd
        'expires' => time() + 3600, // WRONG: should be 1st
    ]
);

// Here's the correct order of the $options array with default values:
$options = [
    'expires' => 0,
    'path' => "",
    'domain' => "",
    'secure' => false,
    'httponly' => false
];

setcookie(
    'my_cookie',
    'my_value',
    $options 
);

?>

If you do not provide options, the default values will be used.
To Top