1. ホーム 
  2. 備忘録 
  3. PHP

クッキー

クッキーについて

PHP は HTTP クッキーを用いてリモートブラウザに文字列データを保存したり、再訪したユーザーを特定したりできる

setcookie() または setrawcookie() を使用してクッキーをセットする

クッキーは HTTP ヘッダの一部であり、クッキーのセットはブラウザに何らかの出力を行う前にコールする必要がある

上記の制約を満たすために、出力バッファ関数などを用いてスクリプトからの出力を遅らせるケースもある

もし variables_order(スーパーグローバルに含める各種変数のパースの要否を定める値)が "C" を含む場合、クライアントからサーバーへ送られた全てのクッキーは自動的に $_COOKIE というスーパーグローバル変数に格納される


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
$name
クッキーの名前
$value
クッキーの値
この値はクライアントのコンピュータに保存されるのでパスワードなどの重要な情報は保存しないようにする
$name が 'cookiename'だとすると、その値は $_COOKIE['cookiename'] でアクセスすることができる
$expires_or_options
クッキーの有効期限
Unix タイムスタンプなので Epoch(1970 年 1 月 1 日)からの経過秒数となる
この値を設定するひとつの方法として、time() が返した値に、期限としたい必要な秒数を加算することが考えられる。
たとえば、time()+60*60*24*30 はクッキーの有効期限を 30 日後にセットする
この値に 0 を設定したり省略したりした場合は、 クッキーはセッションの最後(つまりブラウザを閉じるとき) が有効期限となる
$path
サーバー上での、クッキーを有効としたいパス
'/' をセットすると、クッキーは domain 配下の全てで有効となる。
'/foo/'をセットすると、クッキーは/foo/ディレクトリとそのサブディレクトリ配下で有効となる
デフォルト値はクッキーがセットされたときのカレントディレクトリ
$domain
クッキーが有効な(サブ)ドメイン
これを 'www.example.com' などのサブドメインに設定すると、www サブドメインおよびそれ自身のすべてのサブドメイン( w2.www.example.com など )でクッキーが使えるようになる
サブドメインを含むドメイン全体でクッキーを有効にしたければ、そのドメイン自体( この場合は 'example.com' )を設定する
$secure
クライアントからのセキュアな HTTPS 接続の場合にのみクッキーが送信されるようにする
true を設定すると、セキュアな接続が存在する場合にのみクッキーを設定する
$httponly
true を設定すると、HTTP を通してのみクッキーにアクセスできるようになる。つまり、JavaScriptのようなスクリプト言語からはアクセスできなくなる
この設定を使用すると、XSS 攻撃によって ID を盗まれる危険性を減らせる(が、すべてのブラウザがこの設定をサポートしているわけではない)と言われているが、これはしばしば議論の対象となっている
$options
expires, path, domain, secure, httponly および samesite のうちから、任意のキーを設定可能な連想配列(array)である。
これら以外のキーが存在する場合は E_WARNING レベルの警告が発生する。
戻り値
もしもこの関数をコールする前に何らかの出力がある場合には、setcookie() は失敗し false を返す。
setcookie() が正常に実行されると、true を返す。
この関数では、ユーザーがクッキーを受け入れたかどうかを判断することはできない。


setcookie() は、その他のヘッダ情報と共に送信するクッキーを定義する

前述のとおりクッキーはスクリプトによるあらゆる出力よりも前に送信される必要がある( HTTP プロトコルの制約 )


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


クッキーの value の部分は、クッキーの送信を行う際に自動的に URL エンコードされ、またクッキーを受信した際は、自動的にデコード されてクッキー名と同じ名前の変数に格納される

この挙動が気に入らない場合、 代わりに setrawcookie() を使うことができる

//==================================================//
// クッキーの設定
$value = 'something from somewhere';

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

//==================================================//
// クッキーの参照方法

// 個々のクッキーを表示する
echo $_COOKIE["TestCookie"];

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

クッキーの削除方法


クッキーを削除する場合には、ブラウザの削除機構を起動するために必ず有効期限を過去に設定する必要がある

下記にクッキーの削除の例を記載する

// クッキーの削除

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

クッキーの配列

クッキー名で配列を記述することにより、クッキーの配列を設定することができる

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

// クッキーの配列

// クッキーを設定します
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 
\n"; } }

    参考文献

  1. 公式ドキュメント - cookie
  2. 公式ドキュメント - setcookie