как удалить все куки моего сайта на php


93

Мне интересно, могу ли я удалить все файлы cookie моего веб-сайта, когда пользователь нажимает на выход, потому что я использовал это как функцию для удаления файлов cookie, но она работает неправильно:

setcookie("user",false);

Есть ли способ удалить файлы cookie одного домена в PHP?


В большинстве случаев лучше использовать файлы cookie более разумно и избирательно. Если вы используете сеансы, достаточно одного файла cookie. В любом случае, отслеживайте, какие файлы cookie вы устанавливаете, тогда вам не понадобится какой-то динамический способ их перебора и удаления.
caw

Ответы:


173

PHP setcookie ()

Взято с этой страницы, это отключит все файлы cookie для вашего домена:

// 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


9
Я прочитал этот комментарий, но я действительно не понимаю, почему использование HTTP_COOKIEзначения было бы лучше, чем цикл по $_COOKIEмассиву. У вас есть для этого какие-то причины? Для меня это только похоже на дополнительную (двойную) работу для парсера.
poke

Насколько я могу судить, разницы нет (кроме дополнительной работы).
jasonbar

11
@poke: если имена файлов cookie указаны в виде массива, например: user [имя пользователя], то PHP автоматически создаст соответствующий массив в $ _COOKIE. Вместо этого используйте $ _SERVER ['HTTP_COOKIE'], поскольку он отражает фактические заголовки HTTP-запроса.
Фархади

Как бы вы удалили все файлы cookie, кроме файлов cookie или файлов cookie с заданными значениями?
Chill Web Designs

2
Я видел ситуации, когда есть 2 файла cookie с одинаковым именем, но с разными настройками домена. Один из них попадет в массив $ _COOKIE, а другой - нет. Но они оба будут видны в HTTP_COOKIE. Если вы хотите исправить эту ситуацию, это способ сделать это.
dlo

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

Однако еще лучше запомнить (или где-нибудь сохранить), какие файлы cookie установлены с вашим приложением в домене, и удалить их напрямую.
Таким образом, вы можете быть уверены, что удалили все значения правильно.


2
отличный код, но его недостаточно для использования setcookie( $key, FALSE );?! (см. схему заметок на php.net/manual/en/function.setcookie.php )
Марко Демайо,

@Marco Demaio: Так и должно быть, но я видел это раньше на некоторых серверах. Но конечно, если у вас сработает, просто сделайте так :)
тыкает

это не должно быть вопросом сервера, это PHP делает это внутренне. А зачем /тебе финал setcookie?
Марко Демайо,

@Marco Demaio: Да, под сервером я имел в виду php-сервер. Путь /к файлу cookie. Вам необходимо настроить его так, чтобы вы могли удалить файлы cookie из домена, в противном случае он будет установлен на текущий путь и влияет только на те, которые установлены для текущего пути.
тык

@trante А !? $ key - это не массив, это ключ.
poke

16

Я согласен с некоторыми из приведенных выше ответов. Я бы просто рекомендовал заменить «time () - 1000» на «1». Значение «1» означает 1 января 1970 г., что обеспечивает 100% истечение срока. Следовательно:

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

1
Я всегда задавался вопросом, почему никто не говорит просто сделать это, и это своего рода ответ, который я искал.
Anther

Возможно, в настоящее время это не проблема, но в какой-то момент некоторые браузеры проигнорировали старую дату вместе, и значения не были отброшены, как должны. Я считаю, что IE 7 - один из примеров, который сделал это.
conrad10781

3

убедитесь, что вы вызываете функцию setcookie до того, как на вашем сайте появится какой-либо вывод.

Кроме того, если ваши пользователи выходят из системы, вы также должны удалить / сделать недействительными их переменные сеанса.


2

Когда вы меняете имя своих файлов cookie, вы также можете удалить все файлы cookie, но сохранить один:

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

Также на основе этого PHP-ответа


1
Неправильный синтаксис: 1) в пункте if нет конструкции AS; 2) замените "$ cookies" на $ _COOKIE
Джефф

2

Предоставленные ответы не решили мою проблему,

Не было:

  1. Удалить файлы cookie родительского домена (из abc; удалить bc; файлы cookie),
  2. Удалите файлы cookie с более высокого пути, кроме корневого.

Мой сценарий делает, понимаете.

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

Это не самое красивое / безопасное / оптимальное решение, поэтому используйте его только в том случае, если вы не знаете путь cookie и / или домен cookie. Или используйте идею для создания своей версии.


Идеальное решение,
Шакил Ахмед

1

Вы должны знать, что различные инструменты отслеживания, такие как Google Analytics, также используют файлы cookie в вашем домене, и вы не хотите их удалять, если хотите иметь правильные данные в GA.

Единственное решение, с которым я мог работать, - это установить для существующих файлов cookie значение null. Мне не удалось удалить файлы cookie с клиента.

Итак, для выхода пользователя из системы я использую следующее:

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

Конечно, это не удаляет ВСЕ файлы cookie.


7
Я бы не рекомендовал хранить пароль пользователя в куки. Это серьезная дыра в безопасности, особенно с учетом того, что 0аргумент означает, что cookie даже не зашифровывается при передаче.
Эндрю Энсли

1

Во всех предыдущих ответах упускалось из виду, что setcookieможно было использовать с явным доменом. Кроме того, cookie мог быть установлен на более высоком поддомене, например, если вы были в foo.bar.tar.comдомене, там мог быть установлен cookie tar.com. Таким образом, вы хотите отключить файлы cookie для всех доменов, которые могли их удалить:

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

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

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

    array_shift($host);
}

0

Используйте функцию для очистки файлов cookie:

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

Если вы пройдете, trueон очищает sessionданные, в противном случае данные сеанса сохраняются.


0

Я знаю, что это старый вопрос, но это гораздо более простая альтернатива:

header_remove();

Но будь осторожен! Он удалит ВСЕ заголовки, включая файлы cookie, сеанс и т. Д., Как описано в документации .


на самом деле это ничего не делает для фактического удаления файлов cookie или чего-либо подобного, поскольку браузер просто сохраняет любые сохраненные файлы cookie до истечения срока их действия. хотя это действительно помогает, если другие вещи пытаются порождать файлы cookie и удерживают их от этого.
My1

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

Спасибо за этот фрагмент кода, который может оказать некоторую немедленную помощь. Правильное объяснение значительно повысило бы его ценность в долгосрочной перспективе, показав, почему это хорошее решение проблемы, и сделало бы его более полезным для будущих читателей, задающих другие похожие вопросы. Измените свой ответ, чтобы добавить некоторые пояснения, включая сделанные вами предположения.
Максимилиан Питерс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.