como deletar todos os cookies do meu site em php

92

Gostaria de saber se posso excluir todos os cookies do meu site quando um usuário clicar em logout, porque usei essa função para excluir cookies, mas não está funcionando corretamente:

setcookie("user",false);

Existe uma maneira de excluir os cookies de um domínio no PHP?

Mac Taylor
fonte
Na maioria dos casos, a melhor ideia será usar cookies de maneira mais seletiva. Se você usar sessões, um cookie será suficiente. De qualquer forma, rastreie quais cookies você definiu, então você não precisará de alguma forma dinâmica de iterar sobre eles e excluí-los.
caw

Respostas:

172

PHP setcookie ()

Retirado dessa página, isso cancelará todos os cookies do seu domínio:

// 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
fonte
9
Eu li esse comentário, mas eu realmente não entendo por que usar o HTTP_COOKIEvalor seria melhor do que repetir o $_COOKIEarray. Você tem algum motivo para isso? Para mim, parece apenas mais trabalho (duplo) para o analisador.
poke
Não há nenhuma diferença até onde posso dizer (exceto o trabalho extra).
jasonbar
11
@poke: Se os nomes dos cookies estiverem em notação Array, por exemplo: usuário [nome de usuário] Então o PHP irá criar automaticamente um array correspondente em $ _COOKIE. Em vez disso, use $ _SERVER ['HTTP_COOKIE'], pois ele reflete os cabeçalhos de solicitação HTTP reais.
Farhadi
Como você excluiria todos os cookies, exceto cookies ou cookies com valores definidos?
Chill Web Designs de
2
Já vi situações em que existem 2 cookies com o mesmo nome, mas com configurações de domínio diferentes. Um deles entrará no array $ _COOKIE, e o outro não. Mas ambos estarão visíveis em HTTP_COOKIE. Se você quiser limpar essa situação, esta é a maneira de fazer isso.
dlo
42
$past = time() - 3600;
foreach ( $_COOKIE as $key => $value )
{
    setcookie( $key, $value, $past, '/' );
}

Ainda melhor é lembrar (ou armazená-lo em algum lugar) quais cookies são definidos com seu aplicativo em um domínio e excluí-los diretamente.
Dessa forma, você pode ter certeza de excluir todos os valores corretamente.

cutucar
fonte
2
ótimo código, mas não é suficiente para usar setcookie( $key, FALSE );?! (veja a seção de notas em php.net/manual/en/function.setcookie.php )
Marco Demaio
@Marco Demaio: Deveria ser, mas já vi isso falhar em alguns servidores. Mas é claro, se funcionar para você, faça assim :)
toque
não deveria ser uma questão de servidor, é o PHP que faz isso internamente. E qual a necessidade da final que /você colocou setcookie?
Marco Demaio
@Marco Demaio: Sim, com servidor eu quis dizer o servidor php. O /é o caminho do cookie. Você precisa configurá-lo para que possa remover os cookies do domínio, caso contrário, ele é configurado para o caminho atual e afeta apenas aqueles que são definidos para o caminho atual.
poke
@trante Huh !? $ key não é um array, é uma chave.
clique em
16

Eu concordo com algumas das respostas acima. Eu recomendaria apenas substituir "time () - 1000" por "1". Um valor "1" significa 1º de janeiro de 1970, o que garante a expiração de 100%. Portanto:

setcookie($name, '', 1);
setcookie($name, '', 1, '/');
Doug
fonte
1
Sempre me perguntei por que ninguém diz apenas para fazer isso, e essa é a resposta que estou procurando.
Anther
Possivelmente não é um problema atualmente, mas em um ponto alguns navegadores ignoraram uma data tão antiga todos juntos e os valores não seriam descartados como deveriam. Eu acredito que o IE 7 é um exemplo que fez isso.
conrad10781
3

certifique-se de chamar a função setcookie antes que qualquer saída aconteça em seu site.

além disso, se seus usuários estiverem desconectando, você também deve excluir / invalidar suas variáveis ​​de sessão.

tricô
fonte
2

Quando você altera o nome de seus cookies, você também pode excluir todos os cookies, mas manter um:

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

Também baseado nesta resposta PHP

Roman Holzner
fonte
1
Sintaxe errada: 1) não há construção AS na cláusula if 2) substitua "$ cookies" por $ _COOKIE
Jeff
2

As respostas fornecidas não resolveram meu problema,

Não:

  1. Remover cookies de domínio pai (de abc; remover bc; cookies),
  2. Remova os cookies de um caminho superior diferente do root.

Meu script tem, veja.

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

Não é a solução mais bonita / segura / ótima, então use-a somente se você não souber o caminho do cookie e / ou o domínio do cookie. Ou use a ideia para criar sua versão.

Wesley Abbenhuis
fonte
Solução perfeita,
Shakeel Ahmed
1

Você deve estar ciente de que várias ferramentas de rastreamento, como o Google Analytics, também usam cookies em seu domínio e você não deseja excluí-los, se quiser ter dados corretos no GA.

A única solução que consegui fazer funcionar foi definir os cookies existentes como nulos. Não consegui excluir os cookies do cliente.

Portanto, para desconectar um usuário, eu uso o seguinte:

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

Claro que isso não exclui TODOS os cookies.

Martin LeBlanc
fonte
7
Eu não recomendaria armazenar a senha de um usuário em um cookie. Essa é uma falha de segurança séria, especialmente considerando que o 0argumento significa que o cookie nem mesmo é criptografado em trânsito.
Andrew Ensley
1

Todas as respostas anteriores ignoraram que o setcookiepoderia ter sido usado com um domínio explícito. Além disso, o cookie pode ter sido definido em um subdomínio superior, por exemplo, se você estava em um foo.bar.tar.comdomínio, pode haver um cookie ativado tar.com. Portanto, você deseja cancelar a definição de cookies para todos os domínios que podem ter descartado o cookie:

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

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

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

    array_shift($host);
}
Gajus
fonte
0

Use a função para limpar os 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, '/');
    }
}

Se você passar true, ele limpa os sessiondados, caso contrário, os dados da sessão são preservados.

Dan Bray
fonte
0

Eu sei que esta pergunta é antiga, mas esta é uma alternativa muito mais fácil:

header_remove();

Mas tenha cuidado! Ele apagará TODOS os cabeçalhos, incluindo Cookies, Sessão, etc., conforme explicado nos documentos .

Borjovsky
fonte
isso realmente não faz nada para remover os cookies ou algo semelhante a essa noção, pois o navegador apenas mantém os cookies armazenados até que eles expirem. embora ajude se outras coisas tentarem gerar cookies e impedi-los de fazer isso.
My1
0
<?php
      parse_str(http_build_query($_COOKIE),$arr);
      foreach ($arr as $k=>$v) {
        setCookie("$k","",1000,"/");
      }
Gautam Sharma
fonte
Obrigado por este trecho de código, que pode fornecer alguma ajuda limitada e imediata. Uma explicação adequada melhoraria muito seu valor a longo prazo, mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras questões semelhantes. Edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
Maximilian Peters,