jak usunąć wszystkie pliki cookie z mojej witryny w php

93

Zastanawiam się, czy mogę usunąć wszystkie pliki cookie mojej witryny, gdy użytkownik kliknie wylogowanie, ponieważ użyłem tej funkcji do usuwania plików cookie, ale nie działa ona poprawnie:

setcookie("user",false);

Czy istnieje sposób na usunięcie plików cookie jednej domeny w PHP?

Mac Taylor
źródło
W większości przypadków lepszym pomysłem będzie bardziej selektywne używanie plików cookie. Jeśli korzystasz z sesji, wystarczy jeden plik cookie. W każdym razie, śledź, które pliki cookie ustawisz, a wtedy nie będziesz potrzebować dynamicznego sposobu na ich iterowanie i usuwanie.
krakanie

Odpowiedzi:

173

PHP setcookie ()

Zaczerpnięte z tej strony, spowoduje to usunięcie wszystkich plików cookie w Twojej domenie:

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

jasonbar
źródło
9
Czytałem ten komentarz, ale naprawdę nie rozumiem, dlaczego użycie HTTP_COOKIEwartości byłoby lepsze niż przechodzenie w pętli przez $_COOKIEtablicę. Czy masz ku temu powód? Dla mnie wygląda to na więcej (podwójną) pracę dla parsera.
poke
O ile wiem, nie ma różnicy (z wyjątkiem dodatkowej pracy).
jasonbar
11
@poke: Jeśli nazwy ciasteczek są w notacji tablicowej, np .: użytkownik [nazwa użytkownika] PHP automatycznie utworzy odpowiednią tablicę w $ _COOKIE. Zamiast tego użyj $ _SERVER ['HTTP_COOKIE'], ponieważ odzwierciedla rzeczywiste nagłówki żądań HTTP.
Farhadi
W jaki sposób usunąłbyś wszystkie pliki cookie oprócz plików cookie lub plików cookie z ustawionymi wartościami?
Chill Web Designs
2
Widziałem sytuacje, w których są 2 pliki cookie o tej samej nazwie, ale z różnymi ustawieniami domeny. Jeden z nich trafi do tablicy $ _COOKIE, a drugi nie. Ale oba będą widoczne w HTTP_COOKIE. Jeśli chcesz uporządkować tę sytuację, to jest sposób, aby to zrobić.
dlo
43
$past = time() - 3600;
foreach ( $_COOKIE as $key => $value )
{
    setcookie( $key, $value, $past, '/' );
}

Jeszcze lepiej jest jednak zapamiętać (lub gdzieś je przechowywać), które pliki cookie są ustawione w Twojej aplikacji w domenie i usunąć wszystkie bezpośrednio.
W ten sposób możesz mieć pewność, że wszystkie wartości zostały poprawnie usunięte.

szturchać
źródło
2
świetny kod, ale czy nie wystarczy setcookie( $key, FALSE );?! (patrz przegląd notatek na php.net/manual/en/function.setcookie.php )
Marco Demaio
@Marco Demaio: Powinno być, ale widziałem kiedyś, że zawodziło to na niektórych serwerach. Ale oczywiście, jeśli to zadziała, zrób to tak :)
poke
nie powinno to być kwestia serwera, to PHP robi to wewnętrznie. A jaka jest potrzeba finału, w /którym umieściłeś setcookie?
Marco Demaio
@Marco Demaio: Tak, z serwerem miałem na myśli serwer php. To /jest ścieżka pliku cookie. Musisz to ustawić, aby można było usunąć pliki cookie z domeny, w przeciwnym razie jest ustawiona na bieżącą ścieżkę i wpływa tylko na te, które są ustawione dla bieżącej ścieżki.
poke
@trante Huh !? $ key nie jest tablicą, to klucz.
szturchnij
16

Zgadzam się z niektórymi z powyższych odpowiedzi. Zalecałbym po prostu zamianę „time () - 1000” na „1”. Wartość „1” oznacza 1 stycznia 1970 roku, co gwarantuje wygaśnięcie 100%. W związku z tym:

setcookie($name, '', 1);
setcookie($name, '', 1, '/');
Doug
źródło
1
Zawsze się zastanawiałem, dlaczego nikt nie mówi, żebym to zrobił, i jest to odpowiedź, której szukałem.
Anther
Prawdopodobnie nie jest to obecnie problem, ale w pewnym momencie niektóre przeglądarki zignorowały tak starą datę razem, a wartości nie zostałyby odrzucone tak, jak powinny. Uważam, że IE 7 jest jednym z przykładów, które to zrobiły.
conrad10781
3

upewnij się, że wywołujesz funkcję setcookie, zanim jakiekolwiek dane wyjściowe pojawią się w Twojej witrynie.

również, jeśli Twoi użytkownicy się wylogowują, powinieneś również usunąć / unieważnić ich zmienne sesji.

knittl
źródło
2

Kiedy zmieniasz nazwę swoich plików cookie, możesz również chcieć usunąć wszystkie pliki cookie, ale zachować jeden:

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

Również w oparciu o tę odpowiedź PHP

Roman Holzner
źródło
1
Niewłaściwa składnia: 1) nie ma konstrukcji AS w klauzuli if 2) zamień „$ cookies” na $ _COOKIE
Jeff
2

Podane odpowiedzi nie rozwiązały mojego problemu,

To nie mialo miejsca:

  1. Usuń pliki cookie domeny nadrzędnej (z abc; usuń bc; pliki cookie),
  2. Usuń pliki cookie z wyższej ścieżki innej niż root.

Widzisz, mój skrypt to robi.

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

Nie jest to najbardziej ładne / bezpieczne / optymalne rozwiązanie, więc używaj go tylko wtedy, gdy nie znasz ścieżki pliku cookie i / lub domeny pliku cookie. Lub skorzystaj z pomysłu, aby stworzyć swoją wersję.

Wesley Abbenhuis
źródło
Idealne rozwiązanie,
Shakeel Ahmed,
1

Powinieneś wiedzieć, że różne narzędzia śledzące, takie jak Google Analytics, również używają plików cookie w Twojej domenie i nie chcesz ich usuwać, jeśli chcesz mieć prawidłowe dane w GA.

Jedynym rozwiązaniem, które mogłem uruchomić, było ustawienie istniejących plików cookie na zero. Nie mogłem usunąć plików cookie z klienta.

Dlatego do wylogowania użytkownika używam:

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

Oczywiście nie powoduje to usunięcia WSZYSTKICH plików cookie.

Martin LeBlanc
źródło
7
Nie polecam przechowywania hasła użytkownika w pliku cookie. To poważna luka w zabezpieczeniach, zwłaszcza biorąc pod uwagę 0argument, który oznacza, że ​​plik cookie nie jest nawet szyfrowany podczas przesyłania.
Andrew Ensley,
1

We wszystkich poprzednich odpowiedziach pominięto, że setcookiedomena mogła zostać użyta z jawną domeną. Ponadto plik cookie mógł zostać umieszczony w wyższej subdomenie, np. Jeśli byłeś w foo.bar.tar.comdomenie, może być ustawiony plik cookie tar.com. Dlatego chcesz usunąć pliki cookie dla wszystkich domen, które mogły je usunąć:

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

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

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

    array_shift($host);
}
Gajus
źródło
0

Użyj funkcji, aby wyczyścić pliki 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, '/');
    }
}

Jeśli zdasz true, wyczyści sessiondane, w przeciwnym razie dane sesji zostaną zachowane.

Dan Bray
źródło
0

Wiem, że to pytanie jest stare, ale jest to znacznie łatwiejsza alternatywa:

header_remove();

Ale bądź ostrożny! Spowoduje to usunięcie WSZYSTKICH nagłówków, w tym plików cookie, sesji itp., Jak wyjaśniono w dokumentacji .

Borjovsky
źródło
to naprawdę nie robi nic, aby faktycznie usunąć pliki cookie lub coś podobnego do tego pojęcia, ponieważ przeglądarka po prostu przechowuje wszystkie przechowywane pliki cookie do ich wygaśnięcia. chociaż pomaga, jeśli inne rzeczy próbują tworzyć pliki cookie i uniemożliwiają im to.
Mój 1
0
<?php
      parse_str(http_build_query($_COOKIE),$arr);
      foreach ($arr as $k=>$v) {
        setCookie("$k","",1000,"/");
      }
Gautam Sharma
źródło
Dziękujemy za ten fragment kodu, który może zapewnić ograniczoną, natychmiastową pomoc. Właściwe wyjaśnienie znacznie poprawiłoby jego długoterminową wartość, pokazując, dlaczego jest to dobre rozwiązanie problemu i uczyniłoby go bardziej użytecznym dla przyszłych czytelników z innymi, podobnymi pytaniami. Zmień swoją odpowiedź, dodając wyjaśnienie, w tym przyjęte założenia.
Maximilian Peters