336

When I want to remove a Cookie I try

unset($_COOKIE['hello']);

I see in my cookie browser from firefox that the cookie still exists. How can I really remove the cookie?

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
sanders
  • 10,794
  • 27
  • 85
  • 127
  • 1
    You may find `$cookie->delete()` from https://github.com/delight-im/PHP-Cookie helpful. The code from the question just deletes the property that has been parsed on the server-side. The cookie will still live on on the client side. – caw Jul 12 '16 at 23:34

25 Answers25

374

You May Try this

if (isset($_COOKIE['remember_user'])) {
    unset($_COOKIE['remember_user']); 
    setcookie('remember_user', '', -1, '/'); 
    return true;
} else {
    return false;
}
vee
  • 4,506
  • 5
  • 44
  • 81
Nikunj K.
  • 8,779
  • 4
  • 43
  • 53
  • 1
    i use : if (isset($_COOKIE['remember_user']) && !empty($_COOKIE['remember_user'])) { } – warfish Mar 09 '14 at 03:42
  • 42
    @machineaddict `unset($_COOKIE['Hello']);` is actually important if you might check the cookie somewhere later in the code. – Andreas Hultgren Jun 13 '14 at 12:08
  • @Andreas Hultgren: Well, it depends on how you code. You cannot have that problem. If you have deleted a cookie in the current session, you know it is deleted, what's the point of checking? For the next session it's pointless to `unset($_COOKIE['Hello']);` in the current session. And as session, I refer to a full pageload. – machineaddict Jun 16 '14 at 06:29
  • 4
    working fine but when try to reload page. it saw cookie set with old data why?. – Nilesh patel Jul 21 '15 at 10:39
  • 21
    =======DOES NOT WORK IN CHROME======= I tried this code today and when I access the site using google chrome, and then go into developer tools in chrome, I can see that the expire time is set to 1 second before the epoch (e.g. 1969-12-31 23:59:59) however when I next submit the page the cookie is submitted to the server. When I changed the -1 to 1 (e.g. 1970-01-01 00:00:01) to give the following command: setcookie('Hello', null, 1, '/'); then chrome acted as expected and did not submit the cookie – Peter Hinds May 23 '18 at 10:10
  • 8
    I would definitely not use `-1` for the timestamp. Also, because of timezones, I would use a value of at least `86401` so that way you are in Jan 1970 whatever the locale. It should not be important, but for sure `-1` is not a good idea. – Alexis Wilke Oct 31 '18 at 05:09
  • Along with @PeterHinds comment I just found that setting the value to NULL also throws an error, saying that setcookie() is expecting parameter 2 to be a string. So for anyone else finding this set the value to '' instead of null. – Braeden Black Dec 18 '18 at 22:35
  • 1
    instead of -1 I would do something unsigned older than the current time. For me I find it best just to key in time()-10000 or just a small integer such as 1000 – Oliver M Grech Jan 25 '19 at 11:00
  • I got an error with null as second parameter: setcookie() expects parameter 2 to be string, null given – OGM2 Jan 07 '20 at 12:24
  • this https://stackoverflow.com/a/686166/1262663 should be the correct answer + unset($_COOKIE['hello']) – Grain Mar 14 '20 at 11:20
  • @OGM2 if you are using `declare(strict_types=1);` second parameter MUST be string. Seting null is depracated. – Daniel.P. Jul 23 '20 at 16:35
  • setcookie() expects parameter 2 to be string, null given – Terry Lin Aug 23 '20 at 02:07
  • I don't see any issues saving a username inside a cookie – Kristoffer Tølbøll Nov 25 '21 at 14:16
  • 1
    not working your solution – Siraj Ali Oct 04 '22 at 15:09
315

Set the value to "" and the expiry date to yesterday (or any date in the past)

setcookie("hello", "", time()-3600);

Then the cookie will expire the next time the page loads.

Re0sless
  • 10,678
  • 6
  • 51
  • 66
  • 10
    How about setting the time to 0 (the epoch)? =] – strager Mar 27 '09 at 00:00
  • 12
    If you put a date too far in the past, IE will bark and igores it, i.e. the value will not be removed. – Julien Mar 27 '09 at 00:04
  • 55
    @strager The [manual](http://php.net/manual/en/function.setcookie.php) states: _If set to 0, or omitted, the cookie will expire at the end of the session (when the browser closes)._ That's not really deleting the cookie. I really don't know if IE will do what Julien said, but it's more than possible that IE will do something strange. – yannis May 23 '11 at 10:59
  • 31
    Also, don't forget to actually unset($_COOKIE["hello"]) too, because if there is code on the rest of the page that looks at $_COOKIE["hello"], it will still find it set. I just got bit by this one. – Magmatic Jul 15 '13 at 14:41
  • 13
    Plus it's a good idea to set the path, so setcookie('hello', '', time()-3600, '/'); – Stephan Weinhold Feb 18 '14 at 11:35
  • @Julien I can't find any reference to that which is not your comment. Which version of IE doesn't support this? – Lexi Sep 09 '14 at 08:41
  • 1
    @Julien I tested this against IE6 and this does not seem to be the case. I set "expires" to 1 (1 second after the epoch) and IE6 seems to understand just fine that I want the cookie deleted -- on the next page load, the cookie is gone. – Doktor J Sep 17 '14 at 22:43
  • I found 1 reference to IE8: http://www.vistaheads.com/forums/microsoft-public-internetexplorer-general/357819-ie8-bug-cookie-expiration.html – Julien Sep 19 '14 at 06:11
  • 1
    It may not work when the client's time is not correct. I recommend `setcookie("hello", "", 1)` instead. – Renfei Song Oct 29 '14 at 03:13
  • time()-3600 doesn't work if the user's system date is wrong and set, for example, to 2 days ago (or 2 hours) – the_nuts Sep 11 '15 at 08:54
  • `expiry date to yesterday` : you have set up 1 hr ago. – Pratik Joshi Nov 10 '15 at 06:53
  • 1
    I've passed one hour trying to fix a non-working cookie replacement / unset ! This was due (I don't know why) to the path leaved blank...I replaced it by `'\'` like recommended by @StephanWeinhold and that worked fine.. – TOPKAT Jun 07 '16 at 02:29
  • in case the cookie's domain is not the default one then you have to pass the domain as fourth parameter of setcookie function too, as in general it's good to always set the third (path) and fourth (domain) parameters – sepehr Jul 11 '16 at 10:56
  • 1
    @sepehr what about if the cookie was set with secure flag, and/or httponly flags? Do all the full combination of settings need to be exactly as they are to delete the cookie from the browser? Or can one easily get away with JUST path + domain? – IncredibleHat Nov 28 '17 at 20:34
  • instead of time()-3600 you should set 1 (1 second after unix epoq) – dAm2K Nov 25 '20 at 14:55
264

A clean way to delete a cookie is to clear both of $_COOKIE value and browser cookie file :

if (isset($_COOKIE['key'])) {
    unset($_COOKIE['key']);
    setcookie('key', '', time() - 3600, '/'); // empty value and old timestamp
}
Mouloud
  • 3,715
  • 1
  • 26
  • 20
  • 5
    This is the best method, because you don't need to refresh page! – MaxV Oct 17 '13 at 12:00
  • 22
    I keep going down the page and the answers keep getting better, funny. But this is the best one, stop looking here. – Andrew May 26 '14 at 05:48
  • 25
    FYI, if you set the cookie using a path, you'll need to include the path in this `setcookie` call as well: `setcookie('key', '', time() - 3600, '/');` – Gavin Jun 03 '14 at 23:54
  • 1
    @Gavin Thanks for that tip. I was wondering why it wasn't deleting, but was `unsetting` successfully. – stinkysGTI Nov 20 '14 at 20:16
  • 2
    For anyone that is checking a cookie's existence and cares about cookies that exist with `null` values, you'll need to use [array_key_exists()](http://php.net/array_key_exists) instead, since a cookie with a `null` value won't get found by an `isset()` check. – Leith Aug 05 '16 at 01:47
  • 1
    I've found that if you set the cookie using a `$domain`, you also need to include the domain when clearing the cookie. – user3187724 Jun 05 '20 at 12:55
  • instead of time() - 3600 you should set 1 (1 second after unix epoc) – dAm2K Nov 25 '20 at 14:46
  • No more scrolling. Now, I stop my search for best answer here :) – VijayRana Apr 16 '21 at 09:07
36

To reliably delete a cookie it's not enough to set it to expire anytime in the past, as computed by your PHP server. This is because client computers can and often do have times which differ from that of your server.

The best practice is to overwrite the current cookie with a blank cookie which expires one second after the epoch (1 January 1970 00:00:00 UTC), as so:

setcookie('hello', '', 1);
reformed
  • 4,505
  • 11
  • 62
  • 88
Thejoker123
  • 545
  • 5
  • 11
  • 15
    Correct me if I'm wrong, but setting that to "1" would set it to a second after the epoch, not one second in the future..? I believe you're correct about time zone differences though, so the best solution would be to set it to 2 days in the past (so even the furthest away time zone would still unset the cookie). – PaulSkinner Aug 23 '13 at 10:58
  • @PaulSkinner the epoch date is independent of time zones, the computer does that computation for you. – AlexR May 22 '14 at 07:07
  • 3
    @AlexR Yes. Doesn't really answer my point though. To my understanding, the code above *does* set the cookie to expire in the past (one second past the epoch), unless I am mistaken. – PaulSkinner May 23 '14 at 07:34
  • 12
    +1 for the "1". I don't understand why all others are so fixated on setting a deleted cookie exactly one hour in the past. – Meisner Jul 21 '16 at 13:59
22

That will unset the cookie in your code, but since the $_COOKIE variable is refreshed on each request, it'll just come back on the next page request.

To actually get rid of the cookie, set the expiration date in the past:

// set the expiration date to one hour ago
setcookie("hello", "", time()-3600);
Eric Petroelje
  • 59,820
  • 9
  • 127
  • 177
17

I had the same problem in my code and found that it was a cookie path issue. Check out this stack overflow post: Can't delete php set cookie

I had set the cookie using a path value of "/", but didn't have any path value when I tried to clear it, so it didn't clear. So here is an example of what worked:

Setting the cookie:

$cookiePath = "/";
$cookieExpire = time()+(60*60*24);//one day -> seconds*minutes*hours
setcookie("CookieName",$cookieValue,$cookieExpire,$cookiePath);

Clearing the cookie:

setcookie("cookieName","", time()-3600, $cookiePath);
unset ($_COOKIE['cookieName']);

Hope that helps.

Community
  • 1
  • 1
user3285097
  • 171
  • 1
  • 4
8

This is how PHP v7 setcookie() code works when you do:

<?php
    setcookie('user_id','');
    setcookie('session','');
?>

From the output of tcpdump while sniffing on the port 80, the server sends to the client (Browser) the following HTTP headers:

Set-Cookie: user_id=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0
Set-Cookie: session=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0

Observing packets in the following requests the Browser no longer sends these cookies in the headers

Nulik
  • 6,748
  • 10
  • 60
  • 129
8

Just set the value of cookie to false in order to unset it:

setcookie('cookiename', false);
isherwood
  • 58,414
  • 16
  • 114
  • 157
Amit Merchant
  • 1,045
  • 6
  • 21
8

If you set the cookie to expire in the past, the browser will remove it. See setcookie() delete example at php.net

Alistair Knock
  • 1,806
  • 2
  • 16
  • 25
7

If you want to delete the cookie completely from all your current domain then the following code will definitely help you.

unset($_COOKIE['hello']);
setcookie("hello", "", time() - 300,"/");

This code will delete the cookie variable completely from all your domain i.e; " / " - it denotes that cookie variable's value all set for all domain not just for current domain or path. time() - 300 denotes that it sets to a previous time so it will expire.

Thats how it's perfectly deleted.

Soumen Pasari
  • 145
  • 1
  • 2
  • 11
7

See the sample labelled "Example #2 setcookie() delete example" from the PHP docs. To clear a cookie from the browser, you need to tell the browser that the cookie has expired... the browser will then remove it. unset as you've used it just removes the 'hello' cookie from the COOKIE array.

Jarret Hardie
  • 95,172
  • 10
  • 132
  • 126
5

To delete cookie you just need to set the value to NULL:

"If you've set a cookie with nondefault values for an expiration time, path, or domain, you must provide those same values again when you delete the cookie for the cookie to be deleted properly." Quote from "Learning PHP5" book.

So this code should work(works for me):

Setting the cookie: setcookie('foo', 'bar', time() + 60 * 5);

Deleting the cookie: setcookie('foo', '', time() + 60 * 5);

But i noticed that everybody is setting the expiry date to past, is that necessary, and why?

boksa
  • 223
  • 3
  • 6
  • 1
    It is reliable, that's why. A combination of setting the value to nothing and a time in the past (but not too far as IE occasionally doesn't like it too far back from what I've read) works across the board. – PaulSkinner Aug 23 '13 at 10:51
  • 2
    The empty string `''` is not the same thing as `null`. – orev Jul 30 '17 at 18:58
3

I know that there has been a long time since this topic has been created but I saw a little mistake within this solution (I can call it like that, because it's a detail). I agree that the better solution is probably this solution:

if (isset($_COOKIE['remember_user'])) {
            unset($_COOKIE['Hello']);
            unset($_COOKIE['HelloTest1']);
            setcookie('Hello', null, -1, '/');
            setcookie('HelloTest1', null, -1, '/');
            return true;
        } else {
            return false;
        }

But, in the present case, you delete the cookies in every case where the unset function works and immediately you create new expired cookies in case that the unset function doesn't work.

That means that even if the unset function works, it will still have 2 cookies on the computer. The asked goal, in a logical point of view, is to delete the cookies if it is possible and if it really isn't, make it expire; to get "the cleanest" result.

So, I think we better should do:

if (isset($_COOKIE['remember_user'])) {
            setcookie('Hello', null, -1, '/');
            setcookie('HelloTest1', null, -1, '/');
            unset($_COOKIE['Hello']);
            unset($_COOKIE['HelloTest1']);
            return true;
        } else {
            return false;
        }

Thanks and have a nice day :)

chriszo111
  • 343
  • 5
  • 17
Greg
  • 87
  • 1
  • 8
  • Function unset is meant for PHP's logic (if you want to use the variable $_COOKIE['Hello'], you can't as it is unset). And the function setcookie is meant for the navigator. 2 different purposes, the order of the functions has no impact on the actual code. – Kalzem Jun 18 '14 at 09:36
  • In fact, I known it yep but if you absolutely want to be sure that the cookie has been unset/deleted and so you use the two solutions right up, it would be cleaner to before make theses expire and then unset theses than unset theses and then recreate an expired cookie... if you see what I mean? – Greg Jul 28 '14 at 00:29
  • Yep, sorry replying just now :) I've sent it because I had seen people doing it in the other way.. but it seems more clever like that, i think. – Greg Mar 02 '15 at 19:26
  • Cookie value must be string. In this case, a empty string: `''`. Maybe `null` generates a warning... See [PHP: setcookie()](https://www.php.net/manual/en/function.setcookie.php). – LipESprY Oct 24 '21 at 01:23
2

To remove all cookies you could write:

foreach ($_COOKIE as $key => $value) {
    unset($value);
    setcookie($key, '', time() - 3600);
}
  • 3
    This will not actually remove the cookies unless they have the same path and domain settings as the defaults to setcookie. – Noishe Jan 08 '14 at 08:03
2

Just set the expiration date to one hour ago, if you want to "remove" the cookie, like this:

setcookie ("TestCookie", "", time() - 3600);

or

setcookie ("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);

Source: http://www.php.net/manual/en/function.setcookie.php

You should use the filter_input() function for all globals which a visitor can enter/manipulate, like this:

$visitors_ip = filter_input(INPUT_COOKIE, 'id');

You can read more about it here: http://www.php.net/manual/en/function.filter-input.php and here: http://www.w3schools.com/php/func_filter_input.asp

Jo Smo
  • 6,923
  • 9
  • 47
  • 67
2
$cookie_name = "my cookie";
$cookie_value = "my value";
$cookie_new_value = "my new value";

// Create a cookie,
setcookie($cookie_name, $cookie_value , time() + (86400 * 30), "/"); //86400 = 24 hours in seconds

// Get value in a cookie,
$cookie_value = $_COOKIE[$cookie_name];

// Update a cookie,
setcookie($cookie_name, $cookie_new_value , time() + (86400 * 30), "/");

// Delete a cookie,
setcookie($cookie_name, '' , time() - 3600, "/"); //  time() - 3600 means, set the cookie expiration date to the past hour.
2

It's simple!

setcookie("cookiename", "cookievalue", 1);
L F
  • 29
  • 3
2

I found that in Chrome it's impossible to unset a cookie unless you define the last three parameters in the cookie... The domain, that it's secure and http only...

if (isset($_COOKIE['user_id'])) {
unset($_COOKIE['user_id']); 
setcookie("user_id", "", time() - 3600, "/", 'yourdomain.com',true,true);
header('Location: /');
} else {
/* other code here */
}

This is how I made it work for me. Read the documentation: All about cookies in the official PHP Site

Samuel Ramzan
  • 1,770
  • 1
  • 15
  • 24
1

You can simply use this customize function:

function unset_cookie($cookie_name) {
    if (isset($_COOKIE[$cookie_name])) {
        unset($_COOKIE[$cookie_name]);
        setcookie($cookie_name, null, -1);
    } else { return false; }
}

If you want to remove $_COOKIE['user_account'].
Just use:

unset_cookie('user_account');
Kenny
  • 579
  • 5
  • 8
1

When you enter 0 for time, you mean "now" (+0s from now is actually now) for the browser and it deletes the cookie.

setcookie("key", NULL, 0, "/");

I checked it in chrome browser that gives me:

Name: key
Content: Deleted
Created: Sunday, November 18, 2018 at 2:33:14 PM
Expires: Sunday, November 18, 2018 at 2:33:14 PM
Amir Fo
  • 5,163
  • 1
  • 43
  • 51
  • 3
    No. Just read the docs. "If set to 0, or omitted, the cookie will expire at the end of the session (when the browser closes)." – DrLightman Jan 05 '20 at 20:28
  • @DrLightman Thank you for your attendance, Can you please cite the documentation? – Amir Fo Jan 06 '20 at 20:05
  • 1
    [function.setcookie.php](https://www.php.net/manual/en/function.setcookie.php), **expires** parameter. "If set to 0, or omitted, the cookie will expire at the end of the session (when the browser closes)." – DrLightman Jan 06 '20 at 22:04
1

You could set a session variable based on cookie values

session_start();

if(isset($_COOKIE['loggedin']) && ($_COOKIE['loggedin'] == "true") ){
$_SESSION['loggedin'] = "true";
}

echo ($_SESSION['loggedin'] == "true" ? "You are logged in" : "Please Login to continue");
Jason Plank
  • 2,336
  • 5
  • 31
  • 40
0

I,m used this in php and it worked fine.

function cookie_unset()
{
    setcookie("cookie_name", "", time() - 3600, '/');
    unset ($_COOKIE['cookie_name']);
    //done
}
0

You can use unset or setcookie

unset($_COOKIE['MYCOOKIE']);
//
setcookie('MYCOOKIE', '', -1, '/');

I prefer to check with isset and than unset or setcookie

if(isset($_COOKIE['MYCOOKIE'])) { unset($_COOKIE['MYCOOKIE']); }
//
if(isset($_COOKIE['MYCOOKIE'])) { setcookie('MYCOOKIE', '', -1, '/'); }

this seems to work too, but don't use it in my opinion

setcookie('MYCOOKIE', '', -1, '/') ?? '';
!isset($_COOKIE['MYCOOKIE']) ?: setcookie('MYCOOKIE', '', -1, '/');
Z0OM
  • 1
  • 4
  • 18
  • 29
-2

You have to delete cookies with php in your server and also with js for your browser.. (They has made with php, but cookie files are in the browser client too):

An example:

if ($_GET['action'] == 'exit'){
            // delete cookies with js and then in server with php:
            echo '
            <script type="text/javascript">
                var delete_cookie = function(name) {
                     document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
                };
                delete_cookie("madw");
                delete_cookie("usdw");
            </script>
            ';
unset($_COOKIE['cookie_name']);
unset($_COOKIE['cookie_time']);
  • You don't need JavaScript to set/delete the cookie value. The php function setcookie will do that for you http://php.net/manual/en/function.setcookie.php – Michael Khalili Sep 12 '17 at 15:34
-5

Most of you are forgetting that this will only work on a local machine. On a domain you will need a pattern like this example.

setcookie("example_cookie", 'password', time()-3600, "/", $_SERVER['SERVER_NAME']);
  • 1
    The domain parameter will mean the current domain if it is omitted. – DustWolf Aug 05 '16 at 18:08
  • I meant to say that your answer is incorrect. It will work for any domain, not just the local machine, as it will automatically use the current domain. And your comment means to say you are offended or something? – DustWolf Aug 08 '16 at 13:45
  • 1
    I don't understand why you're getting annoyed at other users if they're pointing out a mistake in your answer. `setcookie` works for any domain, whether localhost or not. – xorinzor Dec 31 '16 at 15:45