アプリ側では、よくあるように次のようにしてCookie を削除していた。

setcookie ( KEY, "", time()-3600, "/" );

このクッキーを削除する際、PHPでは、内部的には値を deleted に設定し、有効期限を365日+1 秒前に設定する


クッキーの用途的に、以下のような手順を踏むと “deleted” な値を取得できる。

  1. ログイン
  2. 別タブでログイン後のページを開く
  3. クライアントPCの時刻を1年以上昔に設定
  4. 片方のタブでログアウトを実行
  5. クッキーの値が “deleted” に設定される
  6. ログアウトしていないタブで、ログイン後の画面に遷移


ext/standard/head.c の setCookie 関数の実装から

if (value && value_len == 0) {
  * MSIE doesn't delete a cookie when you set it to a null value
  * so in order to force cookies to be deleted, even on MSIE, we
  * pick an expiry date 1 year and 1 second in the past
  time_t t = time(NULL) - 31536001; // 注釈 : 31536001 = 60*60*24*365+1
  dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC);
  snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt);

マニュアルには”Common Pitfalls”としてこの仕様がとりあげられているけど、こんな pitfall をわざわざ用意しなくてもと思ってしまった。

Cookies must be deleted with the same parameters as they were set with. If the value argument is an empty string, or FALSE, and all other arguments match a previous call to setcookie, then the cookie with the specified name will be deleted from the remote client. This is internally achieved by setting value to ‘deleted’ and expiration time to one year in past.

Tagged with: , , , ,
Posted in PHP, web

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: