如何删除我的网站在 php 中的所有 Cookie

我想知道当用户点击注销时,我是否可以删除所有网站的 Cookie,因为我用这个函数来删除 Cookie,但是它不能正常工作:

setcookie("user",false);

有没有办法删除 PHP 中某个域的 cookie?

165609 次浏览

make sure you call your setcookie function before any output happens on your site.

also, if your users are logging out, you should also delete/invalidate their session variables.

PHP setcookie()

Taken from that page, this will unset all of the cookies for your domain:

// 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, '/');
}
}

http://www.php.net/manual/en/function.setcookie.php#73484

$past = time() - 3600;
foreach ( $_COOKIE as $key => $value )
{
setcookie( $key, $value, $past, '/' );
}

Even better is however to remember (or store it somewhere) which cookies are set with your application on a domain and delete all those directly.
That way you can be sure to delete all values correctly.

You should be aware of various tracking tools like Google Analytics also use cookies on your domain and you don't want to delete them, if you want to have correct data in GA.

The only solution I could get working was to set the existing cookies to null. I couldn't delete the cookies from the client.

So for logging a user out I use the following:

setcookie("username", null, time()+$this->seconds, "/", $this->domain, 0);
setcookie("password", null, time()+$this->seconds, "/", $this->domain, 0);

Of course this doesn't delete ALL cookies.

I agree with some of the above answers. I would just recommend replacing "time()-1000" with "1". A value of "1" means January 1st, 1970, which ensures expiration 100%. Therefore:

setcookie($name, '', 1);
setcookie($name, '', 1, '/');

When you change the name of your Cookies, you may also want to delete all Cookies but preserve one:

if (isset($_COOKIE)) {
foreach($_COOKIE as $name => $value) {
if ($name != "preservecookie") // Name of the cookie you want to preserve
{
setcookie($name, '', 1); // Better use 1 to avoid time problems, like timezones
setcookie($name, '', 1, '/');
}
}
}

Also based on this PHP-Answer

All previous answers have overlooked that the setcookie could have been used with an explicit domain. Furthermore, the cookie might have been set on a higher subdomain, e.g. if you were on a foo.bar.tar.com domain, there might be a cookie set on tar.com. Therefore, you want to unset cookies for all domains that might have dropped the cookie:

$host = explode('.', $_SERVER['HTTP_HOST']);


while ($host) {
$domain = '.' . implode('.', $host);


foreach ($_COOKIE as $name => $value) {
setcookie($name, '', 1, '/', $domain);
}


array_shift($host);
}

Use the function to clear cookies:

function clearCookies($clearSession = false)
{
$past = time() - 3600;
if ($clearSession === false)
$sessionId = session_id();
foreach ($_COOKIE as $key => $value)
{
if ($clearSession !== false || $value !== $sessionId)
setcookie($key, $value, $past, '/');
}
}

If you pass true then it clears session data, otherwise session data is preserved.

I know this question is old, but this is a much easier alternative:

header_remove();

But be careful! It will erase ALL headers, including Cookies, Session, etc., as explained in the docs.

The provided Answers did not solve my problem,

It did not:

  1. Remove parent domain cookies (from a.b.c; remove b.c; cookies),
  2. Remove cookies from a higher path other then root.

My script does, see.

<?php function unset_cookie($name)
{
$host = $_SERVER['HTTP_HOST'];
$domain = explode(':', $host)[0];


$uri = $_SERVER['REQUEST_URI'];
$uri = rtrim(explode('?', $uri)[0], '/');


if ($uri && !filter_var('file://' . $uri, FILTER_VALIDATE_URL)) {
throw new Exception('invalid uri: ' . $uri);
}


$parts = explode('/', $uri);


$cookiePath = '';
foreach ($parts as $part) {
$cookiePath = '/'.ltrim($cookiePath.'/'.$part, '//');


setcookie($name, '', 1, $cookiePath);


$_domain = $domain;
do {
setcookie($name, '', 1, $cookiePath, $_domain);
} while (strpos($_domain, '.') !== false && $_domain = substr($_domain, 1 + strpos($_domain, '.')));
}
}

It is not the most pretty/safe/optimal solution, so use this only if you do not known the cookie-path and/or cookie-domain's. Or use the idea in order to create your version.

<?php
parse_str(http_build_query($_COOKIE),$arr);
foreach ($arr as $k=>$v) {
setCookie("$k","",1000,"/");
}

I had to add the following to the top answer to actually remove a few cookies that wouldn't go away:

foreach($_COOKIE as $cook) {
setcookie($cook, '', time()-1000);
setcookie($cook, '', time()-1000, '/');
}