PHPでのcookieの削除方法を調べると、よくこんなコードを見かけます。
1 |
setcookie( 'dummy', '', time()-3600); |
上の例だったら dummy という名前を持つcookieに空の値(第2引数)と現在より前の時間(第3引数)を与えて削除するっていう感じのコードですね。
もしかしたらこのコードは ”運よく” 動くことがあるかもしれません。でも環境とかcookieの設定次第ではこの方法は全く効かないことが多々あります。
そこでPHPでcookieが全く削除できないときの対処法について色々まとめてみました。
まず1つめは ヘッダー外でcookieの作成や削除を行ってないか確認する という対策
分かりやすく言うとHTML出力中・後にsetcookieを呼び出しちゃいけないってことです。
このことはPHPマニュアルの setcookieのページ でも次のように言及されています。
ほかのヘッダ情報と同様に、 クッキーは、スクリプトによる他のあらゆる出力よりも前に 送信される必要があります(これはHTTPプロトコルの制約です)。 <html> や <head> タグはもちろん 空白も含め、あらゆる出力よりも前にこの関数をコールするようにしなければなりません。
引用元 : PHP: setcookie - Manual
「タグはもちろん空白も含め」という部分が特に重要で、どんなHTML出力よりも前に setcookie は呼び出されないといけません。それがPHPでcookieを取り扱う時の絶対的ルールです。
例えばHTML出力中にsetcookieを呼び出しているNGコード例は次の通り
1 2 3 4 5 6 7 8 9 10 |
<?php /** HTML出力前の処理 */ ?> <html> <body> <?php /// cookie削除の間違ったコード ?> <?php setcookie('dummy', '', time()-3600); ?> ... |
こういう風にhtmlタグとかbodyタグを出力した後に呼び出すと100%の確率で削除できないです。
なのでcookie削除できないという場合はHTML出力中・後に setcookie を呼び出していないか、よくよく確認した方がいいですね。
ちなみに print_r とか var_export とかでタグ出力する場合も同様です。
お次は setcookieによる削除時にパスまで指定してみる という対処法
実はsetcookie関数の第4引数には、そのcookieが有効になる範囲をパスで指定できます。
例えば次はドメイン直下で dummy という名前のcookieを有効にするコード例
1 2 |
/// パス指定でcookieを作成 setcookie( 'dummy', '1', time()+3600, '/'); |
上コードみたいに第4引数に '/' とドメイン直下からのパス指定をすればOKです。一般的には '/' だけ指定しておけば問題ありません。
そしてこのコードで作成したcookieをパス指定で削除するコード例は次の通り
1 2 |
/// パス指定でcookieを削除 setcookie( 'dummy', '', time()-3600, '/'); |
「PHP cookie 削除方法」で調べてもなぜか出てこないんですが、削除にはかなり有効な方法です。
もしどうやってもcookieが削除できないときは、
- cookie作成時にパス指定('/')しているか
- cookie削除時にもパス指定しているか
ということを確認すると削除できない、ということがほぼなくなるはずです。(経験談)
対処法3.念のためunset関数も実行しておく
最後は cookie変数に対してunset関数を試してみる 、という対策
例えばsetcookie関数で dummy という名前のクッキーを作った場合、グローバル変数 $_COOKIE から次のように参照することができます。
1 2 |
/// cookieの値を取得 $dummy = $_COOKIE['dummy']; |
このcookie変数も削除しておいたほうがいいです。
やり方は簡単で次のようにクッキー変数を直接unset関数に渡すだけ
1 2 |
/// cookie変数を削除する unset( $_COOKIE['dummy'] ); |
まあ必ずやる必要もないんですが念のため・・・
こう書いておけば「cookie削除してるんだな」と人間が見たときも分かりやすいので、一応書いておくと後で役に立つかもしれません。
ここまでのまとめ
ということでcookieが削除できない時の対策をまとめると次の通り
- ヘッダー外にsetcookieしてないか確認する
<html>や<head>はもちろん、HTMLに含まれる空白を出力した後でも setcookie を呼び出すのはNG!setcookieは必ずHTML出力前に呼び出す必要あり
- cookie削除時にパスまで指定してみる
例えば次が setcookie の第4引数にパス指定して削除してるコード例
12/// パス指定でcookieを削除setcookie( 'dummy', '', time()-3600, '/');こういう風に作成時も削除時も第4引数にパス指定すれば(ほぼ)100%確実に削除できる
- unset関数も念のため実行する
例えば dummy というクッキーを削除する場合は次のコード
12/// cookie変数を削除するunset( $_COOKIE['dummy'] );人間が見たときでも削除してると分かりやすいので、一応書いておくのがグッド(かも...)
特に1番目のHTML出力後にsetcookieを呼び出していないか、2番目のパスまで指定してcookie追加・削除できているかは要チェックポイントです。
以上、PHPでcookie削除できないときの対処法でした。ではでは($・・)/~~~