cách xóa tất cả cookie của trang web của tôi trong php


92

Tôi tự hỏi liệu tôi có thể xóa tất cả cookie của trang web của mình khi người dùng nhấp vào đăng xuất hay không, vì tôi đã sử dụng chức năng này làm chức năng xóa cookie nhưng nó không hoạt động bình thường:

setcookie("user",false);

Có cách nào để xóa cookie của một miền trong PHP không?


Trong hầu hết các trường hợp, ý tưởng tốt hơn sẽ là sử dụng cookie một cách có chọn lọc một cách khôn ngoan hơn. Nếu bạn sử dụng phiên, một cookie sẽ là đủ. Dù sao, hãy theo dõi những cookie nào bạn đã đặt, sau đó bạn sẽ không cần một số cách động để lặp lại chúng và xóa chúng.
caw

Câu trả lời:


172

PHP setcookie ()

Được lấy từ trang đó, điều này sẽ hủy đặt tất cả cookie cho miền của bạn:

// 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/ Chức năng.setcookie.php#73484


9
Tôi đọc nhận xét đó, nhưng tôi thực sự không hiểu tại sao sử dụng HTTP_COOKIEgiá trị sẽ tốt hơn bất kỳ vòng lặp nào qua $_COOKIEmảng. Bạn có lý do gì cho điều đó không? Đối với tôi, nó chỉ có vẻ như nhiều hơn (gấp đôi) công việc cho trình phân tích cú pháp.
poke

Không có sự khác biệt nào cho đến nay như tôi có thể nói (ngoại trừ việc làm thêm).
jasonbar

11
@poke: Nếu tên cookie ở ký hiệu Mảng, ví dụ: user [tên người dùng] thì PHP sẽ tự động tạo một mảng tương ứng trong $ _COOKIE. Thay vào đó, hãy sử dụng $ _SERVER ['HTTP_COOKIE'] vì nó phản chiếu các tiêu đề HTTP Request thực.
Farhadi

Làm cách nào để bạn xóa tất cả cookie ngoài cookie hoặc cookie với các giá trị đã đặt?
Chill Web Designs

2
Tôi đã gặp tình huống có 2 cookie có cùng tên nhưng có cài đặt miền khác nhau. Một trong số họ sẽ lọt vào mảng $ _COOKIE, còn người kia thì không. Nhưng cả hai đều sẽ hiển thị trong HTTP_COOKIE. Nếu bạn muốn làm sạch tình trạng này, đây là cách để làm điều đó.
dlo

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

Tuy nhiên, tốt hơn hết là hãy nhớ (hoặc lưu trữ nó ở đâu đó) cookie nào được thiết lập với ứng dụng của bạn trên một miền và xóa tất cả những cookie đó trực tiếp.
Bằng cách đó, bạn có thể chắc chắn xóa tất cả các giá trị một cách chính xác.


2
mã tuyệt vời, nhưng không nên sử dụng setcookie( $key, FALSE );?! (xem Thuyết minh scetion tại php.net/manual/en/function.setcookie.php )
Marco Demaio

@Marco Demaio: Đúng là như vậy, nhưng tôi đã từng thấy lỗi đó trong quá khứ trên một số máy chủ. Nhưng tất nhiên, nếu nó phù hợp với bạn, hãy cứ làm như vậy :)
chọc vào

Nó không phải là vấn đề của máy chủ, mà là PHP thực hiện nó trong nội bộ. Và nhu cầu của trận chung kết /bạn đặt vào là setcookiegì?
Marco Demaio

@Marco Demaio: Vâng, với máy chủ, ý tôi là máy chủ php. Đây /là đường dẫn cookie. Bạn cần đặt nó để có thể xóa cookie khỏi miền, nếu không nó sẽ được đặt thành đường dẫn hiện tại và chỉ ảnh hưởng đến những cookie được đặt cho đường dẫn hiện tại.
poke

@trante Hả !? $ key không phải là một mảng, nó là một khóa.
poke

16

Tôi đồng ý với một số câu trả lời trên. Tôi chỉ khuyên bạn nên thay thế "time () - 1000" bằng "1". Giá trị "1" có nghĩa là ngày 1 tháng 1 năm 1970, đảm bảo 100% hết hạn. Vì thế:

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

1
Tôi luôn tự hỏi tại sao không ai nói chỉ làm điều này, và đó là câu trả lời mà tôi đang tìm kiếm.
Anther

Có thể không phải là vấn đề hiện tại, nhưng tại một số trình duyệt đã bỏ qua một ngày cũ cùng nhau và các giá trị sẽ không bị loại bỏ như bình thường. Tôi tin rằng IE 7 là một ví dụ đã làm được điều này.
conrad10781

3

đảm bảo rằng bạn gọi hàm setcookie của mình trước khi bất kỳ đầu ra nào xảy ra trên trang web của bạn.

ngoài ra, nếu người dùng của bạn đang đăng xuất, bạn cũng nên xóa / làm mất hiệu lực các biến phiên của họ.


2

Khi bạn thay đổi tên Cookie của mình, bạn cũng có thể muốn xóa tất cả Cookie nhưng giữ nguyên một:

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

Cũng dựa trên PHP-Answer này


1
Cú pháp sai: 1) không có cấu trúc AS trong mệnh đề if 2) thay thế "$ cookies" với $ _COOKIE
Jeff

2

Các câu trả lời được cung cấp không giải quyết được vấn đề của tôi,

Nó đã không làm:

  1. Xóa cookie miền mẹ (khỏi abc; xóa bc; cookie),
  2. Xóa cookie khỏi một đường dẫn cao hơn sau đó root.

Kịch bản của tôi không, hãy xem.

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

Đây không phải là giải pháp tốt nhất / an toàn / tối ưu nhất, vì vậy chỉ sử dụng giải pháp này nếu bạn không biết đường dẫn cookie và / hoặc tên miền cookie. Hoặc sử dụng ý tưởng để tạo phiên bản của bạn.


Giải pháp hoàn hảo,
Shakeel Ahmed

1

Bạn nên biết các công cụ theo dõi khác nhau như Google Analytics cũng sử dụng cookie trên tên miền của bạn và bạn không muốn xóa chúng, nếu bạn muốn có dữ liệu chính xác trong GA.

Giải pháp duy nhất tôi có thể làm là đặt các cookie hiện có thành null. Tôi không thể xóa cookie khỏi khách hàng.

Vì vậy, để đăng xuất người dùng, tôi sử dụng như sau:

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

Tất nhiên điều này không xóa TẤT CẢ cookie.


7
Tôi không khuyên bạn nên lưu trữ mật khẩu của người dùng trong cookie. Đó là một lỗ hổng bảo mật nghiêm trọng, đặc biệt khi xem xét 0lập luận có nghĩa là cookie thậm chí không được mã hóa khi chuyển tiếp.
Andrew Ensley

1

Tất cả các câu trả lời trước đó đã bỏ qua rằng setcookiecó thể đã được sử dụng với một miền rõ ràng. Hơn nữa, cookie có thể đã được đặt trên một miền phụ cao hơn, ví dụ: nếu bạn đang ở trên một foo.bar.tar.commiền, có thể có một cookie được đặt trên tar.com. Do đó, bạn muốn hủy đặt cookie cho tất cả các miền có thể đã bỏ cookie:

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

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

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

    array_shift($host);
}

0

Sử dụng chức năng để xóa 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, '/');
    }
}

Nếu bạn vượt qua truethì nó sẽ xóa sessiondữ liệu, nếu không thì dữ liệu phiên được giữ nguyên.


0

Tôi biết câu hỏi này đã cũ, nhưng đây là một giải pháp thay thế dễ dàng hơn nhiều:

header_remove();

Nhưng hãy cẩn thận! Nó sẽ xóa TẤT CẢ các tiêu đề, bao gồm Cookie, Session, v.v., như được giải thích trong tài liệu .


điều này không thực sự làm bất cứ điều gì để thực sự xóa cookie hoặc bất kỳ thứ gì tương tự như khái niệm đó vì trình duyệt chỉ giữ bất kỳ cookie nào được lưu trữ cho đến khi chúng hết hạn. mặc dù nó sẽ giúp ích nếu những thứ khác cố gắng tạo ra cookie và ngăn chúng làm điều đó.
My1

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

Cảm ơn bạn vì đoạn mã này, đoạn mã này có thể cung cấp một số trợ giúp hạn chế, tức thì. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị lâu dài của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ hữu ích hơn cho những người đọc trong tương lai với những câu hỏi tương tự khác. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số giải thích, bao gồm cả những giả định bạn đã đưa ra.
Maximilian Peters
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.