【问题标题】:how to delete all cookies of my website in php如何在php中删除我网站的所有cookie
【发布时间】:2011-01-19 14:44:14
【问题描述】:

我想知道当用户单击注销时是否可以删除我网站的所有 cookie,因为我使用此功能删除 cookie,但它无法正常工作:

setcookie("user",false);

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

【问题讨论】:

  • 在大多数情况下,更好的办法是更明智地有选择地使用 cookie。如果您使用会话,一个 cookie 就足够了。无论如何,跟踪您设置的 cookie,然后您将不需要一些动态的方式来迭代它们并删除它们。

标签: php cookies


【解决方案1】:

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

【讨论】:

  • 我读过那条评论,但我真的不明白为什么使用 HTTP_COOKIE 值会比循环遍历 $_COOKIE 数组更好。你有什么理由吗?对我来说,解析器看起来只需要更多(双重)工作。
  • 据我所知没有区别(除了额外的工作)。
  • @poke: 如果 cookie 名称是数组表示法,例如:user[username] 那么 PHP 会自动在 $_COOKIE 中创建一个对应的数组。而是使用 $_SERVER['HTTP_COOKIE'] 因为它反映了实际的 HTTP 请求标头。
  • 除了 cookie 或具有设定值的 cookie 之外,您将如何删除所有 cookie?
  • 我见过有 2 个 cookie 同名但域设置不同的情况。其中一个将进入 $_COOKIE 数组,而另一个则不会。但它们都将在 HTTP_COOKIE 中可见。如果您想清理这种情况,这就是这样做的方法。
【解决方案2】:
$past = time() - 3600;
foreach ( $_COOKIE as $key => $value )
{
    setcookie( $key, $value, $past, '/' );
}

然而,更好的是记住(或将其存储在某处)您的应用程序在域上设置了哪些 cookie,然后直接删除所有这些。
这样您就可以确保正确删除所有值。

【讨论】:

  • 很棒的代码,但是还不够用setcookie( $key, FALSE );?! (请参阅php.net/manual/en/function.setcookie.php 的注释部分)
  • @Marco Demaio:应该是这样,但我过去曾在某些服务器上看到过这种情况。但是,当然,如果它对你有用,那就这样做吧:)
  • 这不应该是服务器的问题,它是 PHP 在内部完成的。你放在setcookie 中的最后一个/ 需要什么?
  • @Marco Demaio:是的,服务器是指 php 服务器。 / 是 cookie 路径。您需要设置它,以便您可以从域中删除 cookie,否则它会设置为当前路径,并且只影响为当前路径设置的那些。
  • @trante 嗯!? $key 不是一个数组,它是一个键。
【解决方案3】:

我同意上面的一些答案。我只是建议用“1”替换“time()-1000”。值“1”表示 1970 年 1 月 1 日,确保 100% 到期。因此:

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

【讨论】:

  • 我一直想知道为什么没有人说要这样做,而这正是我一直在寻找的答案。
  • 目前可能不是问题,但有一次一些浏览器忽略了一个旧的日期,并且这些值不会被丢弃。我相信 IE 7 就是这样做的一个例子。
【解决方案4】:

提供的答案并没有解决我的问题,

它没有:

  1. 删除父域 cookie(从 a.b.c;删除 b.c;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 域的情况下才使用它。或者使用这个想法来创建你的版本。

【讨论】:

  • 完美解决方案,
【解决方案5】:

确保在您的网站上发生任何输出之前调用您的 setcookie 函数。

此外,如果您的用户正在注销,您还应该删除/使他们的会话变量无效。

【讨论】:

    【解决方案6】:

    当您更改 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-Answer

    【讨论】:

    • 语法错误:1) if 子句中没有 AS 结构 2) 用 $_COOKIE 替换 "$cookies"
    【解决方案7】:

    您应该知道各种跟踪工具(例如 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。

    【讨论】:

    • 我不建议将用户密码存储在 cookie 中。这是一个严重的安全漏洞,尤其是考虑到 0 参数意味着 cookie 在传输过程中甚至没有加密。
    【解决方案8】:

    所有先前的答案都忽略了setcookie 可能已与显式域一起使用。此外,cookie 可能已设置在更高的子域上,例如如果您在 foo.bar.tar.com 域上,则可能在 tar.com 上设置了 cookie。因此,您希望为所有可能已丢弃 cookie 的域取消设置 cookie:

    $host = explode('.', $_SERVER['HTTP_HOST']);
    
    while ($host) {
        $domain = '.' . implode('.', $host);
    
        foreach ($_COOKIE as $name => $value) {
            setcookie($name, '', 1, '/', $domain);
        }
    
        array_shift($host);
    }
    

    【讨论】:

      【解决方案9】:

      使用该功能清除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, '/');
          }
      }
      

      如果您传递true,则它会清除session 数据,否则会话数据会被保留。

      【讨论】:

        【解决方案10】:

        我知道这个问题很老,但这是一个更简单的选择:

        header_remove();
        

        但要小心!如the docs 中所述,它将清除所有标头,包括 Cookie、Session 等。

        【讨论】:

        • 这并没有真正删除 cookie 或任何类似的概念,因为浏览器只是保留任何存储的 cookie 直到它们过期。尽管如果其他事物试图生成 cookie 并阻止它们这样做,它确实会有所帮助。
        【解决方案11】:
        <?php
              parse_str(http_build_query($_COOKIE),$arr);
              foreach ($arr as $k=>$v) {
                setCookie("$k","",1000,"/");
              }
        

        【讨论】:

        • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。一个适当的解释将通过展示为什么这是解决问题的好方法来极大地提高其长期价值,并使其对有其他类似问题的未来读者更有用。请编辑您的答案以添加一些解释,包括您所做的假设。
        【解决方案12】:

        我必须在最佳答案中添加以下内容,才能真正删除一些不会消失的 cookie:

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

        【讨论】:

        • 这不会取消设置 cookie,因为 foreach 语法。它将使用您的 cookie 的 设置新的 cookie。此外,如果您的 cookie 值包含问题字符,这可能会导致 PHP 警告。
        猜你喜欢
        • 1970-01-01
        • 2018-04-19
        • 2010-11-26
        • 2011-09-18
        • 2010-12-27
        • 1970-01-01
        • 2016-01-08
        • 2011-10-01
        相关资源
        最近更新 更多