Wie lösche ich alle Cookies meiner Website in PHP

92

Ich frage mich, ob ich alle Cookies meiner Website löschen kann, wenn ein Benutzer auf Abmelden klickt, da ich diese Funktion zum Löschen von Cookies verwendet habe, sie jedoch nicht ordnungsgemäß funktioniert:

setcookie("user",false);

Gibt es eine Möglichkeit, die Cookies einer Domain in PHP zu löschen?

Mac Taylor
quelle
In den meisten Fällen ist es die bessere Idee, Cookies klüger und selektiver einzusetzen. Wenn Sie Sitzungen verwenden, ist ein Cookie ausreichend. Verfolgen Sie auf jeden Fall, welche Cookies Sie gesetzt haben, dann brauchen Sie keine dynamische Methode, um sie zu durchlaufen und zu löschen.
Caw

Antworten:

171

PHP setcookie ()

Auf dieser Seite werden alle Cookies für Ihre Domain gelöscht:

// 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
quelle
9
Ich habe diesen Kommentar gelesen, aber ich verstehe wirklich nicht, warum die Verwendung des HTTP_COOKIEWerts besser wäre, als das $_COOKIEArray zu durchlaufen . Hast du einen Grund dafür? Für mich sieht es nur nach mehr (doppelter) Arbeit für den Parser aus.
Poke
Soweit ich das beurteilen kann, gibt es keinen Unterschied (außer der zusätzlichen Arbeit).
Jason Bar
11
@poke: Wenn Cookie-Namen in Array-Notation vorliegen, z. B.: user [Benutzername], erstellt PHP automatisch ein entsprechendes Array in $ _COOKIE. Verwenden Sie stattdessen $ _SERVER ['HTTP_COOKIE'], da es die tatsächlichen HTTP-Anforderungsheader widerspiegelt.
Farhadi
Wie würden Sie alle Cookies außer Cookies oder Cookies mit festgelegten Werten löschen?
Chill Web Designs
2
Ich habe Situationen gesehen, in denen es 2 Cookies mit demselben Namen, aber unterschiedlichen Domain-Einstellungen gibt. Einer von ihnen schafft es in das $ _COOKIE-Array, der andere nicht. Beide werden jedoch in HTTP_COOKIE angezeigt. Wenn Sie diese Situation bereinigen möchten, ist dies der richtige Weg.
dlo
42
$past = time() - 3600;
foreach ( $_COOKIE as $key => $value )
{
    setcookie( $key, $value, $past, '/' );
}

Noch besser ist es jedoch, sich zu merken (oder irgendwo zu speichern), welche Cookies mit Ihrer Anwendung auf einer Domain gesetzt werden, und alle diese Cookies direkt zu löschen.
Auf diese Weise können Sie sicher sein, alle Werte korrekt zu löschen.

Sack
quelle
2
toller Code, aber nicht genug zu verwenden setcookie( $key, FALSE );?! (Siehe Notes Scetion unter php.net/manual/en/function.setcookie.php )
Marco Demaio
@ Marco Demaio: Es sollte sein, aber ich habe gesehen, dass dies in der Vergangenheit auf einigen Servern fehlgeschlagen ist. Aber natürlich, wenn es für Sie funktioniert, machen Sie es einfach so :)
stupsen Sie
Es sollte keine Frage des Servers sein, es ist das PHP, das dies intern erledigt. Und was braucht das Finale, in dem /du platziert bist setcookie?
Marco Demaio
@ Marco Demaio: Ja, mit Server meinte ich den PHP-Server. Das /ist der Cookie-Pfad. Sie müssen es so einstellen, dass Sie die Cookies aus der Domäne entfernen können. Andernfalls wird es auf den aktuellen Pfad gesetzt und wirkt sich nur auf diejenigen aus, die für den aktuellen Pfad festgelegt sind.
stupsen
@ Trante Huh!? $ key ist kein Array, sondern ein Schlüssel.
stupsen
16

Ich stimme einigen der obigen Antworten zu. Ich würde nur empfehlen, "time () - 1000" durch "1" zu ersetzen. Ein Wert von "1" bedeutet den 1. Januar 1970, wodurch der Ablauf zu 100% sichergestellt wird. Deshalb:

setcookie($name, '', 1);
setcookie($name, '', 1, '/');
Doug
quelle
1
Ich habe mich immer gefragt, warum niemand sagt, dass er das einfach tun soll, und das ist die Antwort, nach der ich gesucht habe.
Anther
Möglicherweise derzeit kein Problem, aber irgendwann haben einige Browser ein so altes Datum ignoriert, und die Werte wurden nicht so verworfen, wie sie sollten. Ich glaube, IE 7 ist ein Beispiel dafür.
conrad10781
3

Stellen Sie sicher, dass Sie Ihre Setcookie-Funktion aufrufen, bevor eine Ausgabe auf Ihrer Site erfolgt.

Wenn sich Ihre Benutzer abmelden, sollten Sie auch ihre Sitzungsvariablen löschen / ungültig machen.

stricken
quelle
2

Wenn Sie den Namen Ihrer Cookies ändern, möchten Sie möglicherweise auch alle Cookies löschen, aber eines beibehalten:

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

Auch basierend auf dieser PHP-Antwort

Roman Holzner
quelle
1
Falsche Syntax: 1) Es gibt kein AS-Konstrukt in if-Klausel 2) Ersetzen Sie "$ cookies" durch $ _COOKIE
Jeff
2

Die bereitgestellten Antworten haben mein Problem nicht gelöst.

Es hat nicht:

  1. Entfernen Sie übergeordnete Domain-Cookies (von abc; entfernen Sie bc; Cookies),
  2. Entfernen Sie Cookies von einem höheren Pfad als root.

Mein Skript funktioniert.

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

Es ist nicht die schönste / sicherste / optimale Lösung. Verwenden Sie diese Lösung daher nur, wenn Sie den Cookie-Pfad und / oder die Cookie-Domain nicht kennen. Oder verwenden Sie die Idee, um Ihre Version zu erstellen.

Wesley Abbenhuis
quelle
Perfekte Lösung,
Shakeel Ahmed
1

Sie sollten wissen, dass verschiedene Tracking-Tools wie Google Analytics auch Cookies in Ihrer Domain verwenden und diese nicht löschen möchten, wenn Sie korrekte Daten in GA haben möchten.

Die einzige Lösung, die ich zum Laufen bringen konnte, bestand darin, die vorhandenen Cookies auf null zu setzen. Ich konnte die Cookies nicht vom Client löschen.

Um einen Benutzer abzumelden, verwende ich Folgendes:

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

Dies löscht natürlich nicht ALLE Cookies.

Martin LeBlanc
quelle
7
Ich würde nicht empfehlen, das Passwort eines Benutzers in einem Cookie zu speichern. Dies ist eine schwerwiegende Sicherheitslücke, insbesondere angesichts des 0Arguments, dass das Cookie während der Übertragung nicht einmal verschlüsselt wird.
Andrew Ensley
1

Alle vorherigen Antworten haben übersehen, dass das setcookiemit einer expliziten Domain hätte verwendet werden können. Darüber hinaus wurde das Cookie möglicherweise auf eine höhere Subdomain gesetzt, z. B. wenn Sie sich in einer foo.bar.tar.comDomain befanden , wurde möglicherweise ein Cookie gesetzt tar.com. Daher möchten Sie Cookies für alle Domains deaktivieren, die das Cookie möglicherweise gelöscht haben:

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

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

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

    array_shift($host);
}
Gajus
quelle
0

Verwenden Sie die Funktion, um Cookies zu löschen:

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

Wenn Sie bestehen true, werden die sessionDaten gelöscht , andernfalls bleiben die Sitzungsdaten erhalten.

Dan Bray
quelle
0

Ich weiß, dass diese Frage alt ist, aber dies ist eine viel einfachere Alternative:

header_remove();

Aber sei vorsichtig! Es werden ALLE Header gelöscht, einschließlich Cookies, Sitzungen usw., wie in den Dokumenten erläutert .

Borjovsky
quelle
Dies bewirkt eigentlich nichts, um Cookies oder ähnliches zu entfernen, da der Browser gespeicherte Cookies nur so lange aufbewahrt, bis sie ablaufen. obwohl es hilfreich ist, wenn andere Dinge versuchen, Cookies zu erzeugen, und sie davon abhalten, dies zu tun.
My1
0
<?php
      parse_str(http_build_query($_COOKIE),$arr);
      foreach ($arr as $k=>$v) {
        setCookie("$k","",1000,"/");
      }
Gautam Sharma
quelle
Vielen Dank für dieses Code-Snippet, das möglicherweise nur begrenzte und sofortige Hilfe bietet. Eine richtige Erklärung würde ihren langfristigen Wert erheblich verbessern, indem sie zeigt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen, ähnlichen Fragen nützlicher machen. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der von Ihnen getroffenen Annahmen.
Maximilian Peters