PHP 8.4.0 RC4 available for testing

setcookie

(PHP 4, PHP 5, PHP 7, PHP 8)

setcookieEnvia um cookie

Descrição

setcookie(
    string $name,
    string $value = "",
    int $expires_or_options = 0,
    string $path = "",
    string $domain = "",
    bool $secure = false,
    bool $httponly = false
): bool

Assinatura alternativa disponível a partir do PHP 7.3.0 (sem suporte a parâmetros nomeados):

setcookie(string $name, string $value = "", array $options = []): bool

A função setcookie() define um cookie para ser enviado juntamente com os cabeçalhos HTTP. Como outros cabeçalhos, os cookies devem ser enviados antes de qualquer saída do script (isso é uma restrição do protocolo). Isso significa que as chamadas a essa função devem ser colocadas antes de qualquer saída, incluindo as tags <html> e <head>, assim como espaços em branco.

Uma vez que os cookies foram definidos, eles podem ser acessados no próximo carregamento da página através do array $_COOKIE. Os valores dos cookies também podem existir no array $_REQUEST.

Parâmetros

A » RFC 6265 fornece a referência normativa de como cada parâmetro de setcookie() é interpretado.

name

O nome do cookie.

value

O valor do cookie. Esse valor é armazenado no computador do cliente; não deve ser armazenada informação sensível. Supondo que o name seja 'cookiename', o valor pode ser lido através de $_COOKIE['cookiename']

expires_or_options

O tempo para o cookie expirar. Esse valor é um timestamp Unix, portanto é o número de segundos desde a época Unix. Uma maneira de configurar esse valor é adicionando o número de segundos em que o cookie deve durar antes de expirar ao resultado da função time(). Por exemplo, time()+60*60*24*30 irá configurar o cookie para expirar em 30 dias. Outra opção é usar a função mktime(). Se configurado para 0 ou omitido, o cookie vai expirar no final da sessão (quando o navegador fechar).

Nota:

O parâmetro expires_or_options recebe uma timestamp Unix, ao contrário do formato de data Wdy, DD-Mon-YYYY HH:MM:SS GMT, isso acontece porque o PHP faz essa conversão internamente.

path

O caminho no servidor onde o cookie estará disponível. Se configurado para '/', o cookie estará disponível para todo o domain. Se configurado para o diretório '/foo/', o cookie estará disponível apenas dentro do diretório /foo/ e todos os subdiretórios como /foo/bar/ do domain. O valor padrão é o diretório atual onde o cookie está sendo configurado.

domain

O (sub)domínio para qual o cookie estará disponível. Definindo para um subdomínio (como 'www.example.com') deixará o cookie disponível para aquele subdomínio e todos os outros sub-domínios abaixo dele (exemplo w2.www.example.com). Para deixar o cookie disponível para todo o domínio (incluindo todos os subdomínios dele), basta definir o valor para o nome do domínio ('example.com', nesse caso).

Navegadores antigos ainda implementam a » RFC 2109 e podem requerer um . no início para funcionar com todos os subdomínios.

secure

Indica que o cookie só poderá ser transmitido sob uma conexão segura HTTPS do cliente. Quando configurado para true, o cookie será enviado somente se uma conexão segura existir. No lado do servidor, fica por conta do programador enviar esse tipo de cookie somente sob uma conexão segura (ex respeitando $_SERVER["HTTPS"]).

httponly

Quando for true, o cookie será acessível somente sob o protocolo HTTP. Isso significa que o cookie não será acessível por linguagens de script, como JavaScript. É dito que essa configuração pode ajudar a reduzir ou identificar roubos de identidade através de ataques do tipo XSS (entretanto ela não é suportada por todos os navegadores), mas essa informação é constantemente discutida. Foi adicionada no PHP 5.2.0. true ou false

options

Um array associativo que pode ter qualquer uma das chaves expires, path, domain, secure, httponly e samesite. Se qualquer outra chave estiver presente, um alerta E_WARNING é gerado. Os valores têm o mesmo efeito como descrito para os parâmetros de mesmo nome. O valor do elemento samesite deve ser None, Lax ou Strict. Se uma das opções não for informada, os valores padrão serão os mesmos valores padrão dos parâmetros explícitos. Se samesite for omitido, o atributo SameSite do cookie não será atribuído.

Nota:

Para definir um cookie que inclui atributos que não estão entre as chaves listadas, use a função header().

Valor Retornado

Se houver saída antes da chamada dessa função, setcookie() irá falhar e retornará false. Se a função setcookie() for executada com sucesso, ela retornará true. Isso não indica que o usuário aceitou o cookie.

Registro de Alterações

Versão Descrição
8.2.0 O formato de data do cookie agora é 'D, d M Y H:i:s \G\M\T'; anteriormente era 'D, d-M-Y H:i:s T'.
7.3.0 Uma assinatura alternativa para suportar o array options foi adicionado. Essa assinatura também permite configurar o atributo SameSite do cookie.

Exemplos

Os exemplos a seguir demonstram algumas formas de enviar cookies.

Exemplo #1 Exemplo de setcookie() para enviar cookies

<?php

$value
= 'alguma coisa de algum lugar';

setcookie("CookieTeste", $value);
setcookie("CookieTeste", $value, time()+3600); /* expira em 1 hora */
setcookie("CookieTeste", $value, time()+3600, "/~rasmus/", "example.com", true);

?>

Note que a porção do valor do cookie será automaticamente codificada em URL quando o cookie for enviado, e quando ele for recebido, será automaticamente decodificado e atribuído a uma variável com o mesmo nome do cookie. Se esta não for a intenção, pode ser utilizada em seu lugar a função setrawcookie(). Para ver o conteúdo do cookie de teste em um script, simplesmente utilize um dos exemplos abaixo:

<?php
// Mostra um cookie individual
echo $_COOKIE["CookieTeste"];

// Outra maneira de depurar/testar é vendo todos os cookies
print_r($_COOKIE);
?>

Exemplo #2 Exemplo de setcookie() para apagar cookies

Quando um cookie estiver sendo excluído, deve-se garantir que a data de expiração dele está no passado, para acionar o mecanismo de remoção no navegador. O exemplo a seguir mostra como excluir os cookies enviados no exemplo anterior:

<?php
// Configura a data de expiração para uma hora atrás
setcookie("CookieTeste", "", time() - 3600);
setcookie("CookieTeste", "", time() - 3600, "/~rasmus/", ".example.com", 1);
?>

Exemplo #3 setcookie() e arrays

Cookies de array também podem ser enviados, utilizando a notação de array no nome dele. Isso tem o efeito de enviar tantos cookies quantos elementos houver no array, mas quando o cookie for recebido pelo script, os valores serão todos colocados em um array com o nome do cookie:

<?php
// envia os cookies
setcookie("cookie[tres]", "cookietres");
setcookie("cookie[dois]", "cookiedois);
setcookie("
cookie[um]", "cookieum");

// Mostra os cookies depois que a página recarregar
if (isset(
$_COOKIE['cookie'])) {
foreach (
$_COOKIE['cookie'] as $nome => $valor) {
$nome = htmlspecialchars($nome);
$valor = htmlspecialchars($valor);
echo "
$nome : $valor <br />\n";
}
}
?>

O exemplo acima produzirá:

tres : cookietres
dois : cookiedois
um : cookieum

Nota: Utilizar caracteres como [ e ] no nome do cookie não é válido conforme a RFC 6265, seção 4, mas deve ser suportado por navegadores conforme a RFC 6265, seção 5.

Notas

Nota:

Você pode utilizar o buffer de saída para enviar a saída antes de chamar essa função, com o custo de toda a saída para o navegador ser armazenada em buffer no servidor até que seja enviada. Isso pode ser feito chamando ob_start() e ob_end_flush() no script, ou configurando a diretiva output_buffering no php.ini ou em arquivos de configuração do servidor.

Problemas comuns:

  • Os cookies não estarão disponíveis até o próximo carregamento da página para a qual o cookie deverá estar visível. Para testar se um cookie foi enviado com sucesso, deve ser verificado o cookie no próximo carregamento da página antes que ele expire. O tempo para expirar é configurado pelo parâmetro expires_or_options. Uma boa maneira de depurar a existência dos cookies é chamando a função print_r($_COOKIE);.
  • Os cookies devem ser excluídos com os mesmos parâmetros com os quais foram configurados. Se o argumento value for uma string vazia, e todos os outros argumentos forem iguais à chamada anterior de setcookie(), o cookie com o nome especificado será excluído do cliente remoto. Internamente, isso é feito colocando o valor do cookie para 'deleted' e a data de expiração para um ano no passado.
  • Quando um cookie for configurado com o valor false, será realizada uma tentativa de excluir o cookie. Portanto, evite utilizar valores booleanos. No lugar deles, utilize 0 para false e 1 para true.
  • Nomes de cookies podem ser configurados como arrays e estarão disponíves para os scripts PHP como arrays, mas cookies separados serão armazenados no sistema do usuário. Deve ser considerado utilizar explode() para enviar um cookie com nomes e valores múltiplos. Não é recomendado o uso da função serialize() para esse propósito, pois pode resultar em furos de segurança.

Várias chamadas para a função setcookie() são feitas na ordem em que são chamadas.

Veja Também

adicione uma nota

Notas Enviadas por Usuários (em inglês) 13 notes

up
388
walterquez
12 years ago
Instead of this:
<?php setcookie( "TestCookie", $value, time()+(60*60*24*30) ); ?>

You can this:
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
up
266
Bachsau
12 years ago
Want to remove a cookie?

Many people do it the complicated way:
setcookie('name', 'content', time()-3600);

But why do you make it so complicated and risk it not working, when the client's time is wrong? Why fiddle around with time();

Here's the easiest way to unset a cookie:
setcookie('name', 'content', 1);

Thats it.
up
89
Anonymous
4 years ago
Just an example to clarify the use of the array options, especially since Mozilla is going to deprecate / penalise the use of SameSite = none, which is used by default if not using array options.

<?php
$arr_cookie_options
= array (
'expires' => time() + 60*60*24*30,
'path' => '/',
'domain' => '.example.com', // leading dot for compatibility or use subdomain
'secure' => true, // or false
'httponly' => true, // or false
'samesite' => 'None' // None || Lax || Strict
);
setcookie('TestCookie', 'The Cookie Value', $arr_cookie_options);
?>
up
35
paul nospam AT nospam sitepoint dot com
17 years ago
Note when setting "array cookies" that a separate cookie is set for each element of the array.

On high traffic sites, this can substantially increase the size of subsequent HTTP requests from clients (including requests for static content on the same domain).

More importantly though, the cookie specification says that browsers need only accept 20 cookies per domain. This limit is increased to 50 by Firefox, and to 30 by Opera, but IE6 and IE7 enforce the limit of 20 cookie per domain. Any cookies beyond this limit will either knock out an older cookie or be ignored/rejected by the browser.
up
21
nacho at casinelli dot com
7 years ago
It's worth a mention: you should avoid dots on cookie names.

<?php
// this will actually set 'ace_fontSize' name:
setcookie( 'ace.fontSize', 18 );
?>
up
42
Anonymous
17 years ago
something that wasn't made clear to me here and totally confused me for a while was that domain names must contain at least two dots (.), hence 'localhost' is invalid and the browser will refuse to set the cookie! instead for localhost you should use false.

to make your code work on both localhost and a proper domain, you can do this:

<?php

$domain
= ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
setcookie('cookiename', 'data', time()+60*60*24*365, '/', $domain, false);

?>
up
17
gabe at fijiwebdesign dot com
17 years ago
If you want to delete all cookies on your domain, you may want to use the value of:

<?php $_SERVER['HTTP_COOKIE'] ?>

rather than:

<?php $_COOKIE ?>

to dertermine the cookie names.
If cookie names are in Array notation, eg: user[username]
Then PHP will automatically create a corresponding array in $_COOKIE. Instead use $_SERVER['HTTP_COOKIE'] as it mirrors the actual HTTP Request header.

<?php

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

?>
up
9
synnus at gmail dot com
4 years ago
The " PHPSESSID " cookie will soon be rejected because its " sameSite " attribute is set to " none " or an invalid value, and without " secure " attribute. To learn more about the "sameSite" attribute, visit https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite.

<?php
ini_set
("session.cookie_secure", 1);
session_start();

my PHP code ....

?>
up
8
ellert at vankoperen dot nl
10 years ago
Caveat: if you use URL RewriteRules to get stuff like this: domain.com/bla/stuf/etc into parameters, you might run into a hickup when setting cookies.
At least in my setup a change in one of the parameters resulted in the cookie not being 'there' anymore.
The fix is simple: specify the domain. '/' will usualy do fine.
up
4
laffen
15 years ago
Note that the $_COOKIE variable not will hold multiple cookies with the same name. It is legitimate to set two cookies with the same name to the same host where the sub domain is different.
<?php
setcookie
("testcookie", "value1hostonly", time(), "/", ".example.com", 0, true);
setcookie("testcookie", "value2subdom", time(), "/", "subdom.example.com", 0, true);
?>
The next request from the browser will have both cookies in the $_SERVER['HTTP_COOKIE'] variable, but only one of them will be found in the $_COOKIE variable. Requests to subdom.example.com will have both cookies, while browser request to example.com or www.example.com only sends the cookie with the "value1hostonly" value.

<?php
$kaker
= explode(";", $_SERVER['HTTP_COOKIE']);
foreach(
$kaker as $val){
$k = explode("=", $val);
echo
trim($k[0]) . " => " . $k[1];
}

// output
testcookie => value1hostonly
testcookie
=> value2subdom

?>
up
3
Anonymous
14 years ago
A period in a cookie name (like user.name) seems to show up in the $_COOKIE array as an underscore (so user_name). This means that for example $_COOKIE["user_name"] must be used to read a cookie that has been set with setcookie("user.name" ...), which is already rather confusing.

Furthermore the variable $_COOKIE["user_name"] will retain the value set by setcookie("user.name" ...) and no amount of calling setcookie("user_name" ...) will alter this value. This is rather trivially fixed by clearing the "user.name" cookie, but it can take a while to realize this since there's only "user_name" in $_COOKIE.

Hope this saves someone some time.
up
0
ilya at ilya dot top
2 months ago
In any web browser there is a very commonly used option "Open previous windows and tabs" which is disabled by default, but many people enable it.
When this option is active, the web browser, when closing and reopening, instead of executing the termination and starting a new session, saves and restores the current session along with session cookies and sessionStorage.
Both session cookies and sessionStorage, contrary to expectations, can live for a very long time until the user closes the tab before closing the web browser.
If you want a cookie, for example with a time offset, to be guaranteed to have a short lifetime, you should explicitly specify this short lifetime, rather than relying on self-deletion on the session cookie.
up
-1
hansel at gretel dot com
18 years ago
The following code snippet combines abdullah's and Charles Martin's examples into a powerful combination function (and fixes at least one bug in the process):

<?php
function set_cookie_fix_domain($Name, $Value = '', $Expires = 0, $Path = '', $Domain = '', $Secure = false, $HTTPOnly = false)
{
if (!empty(
$Domain))
{
// Fix the domain to accept domains with and without 'www.'.
if (strtolower(substr($Domain, 0, 4)) == 'www.') $Domain = substr($Domain, 4);
$Domain = '.' . $Domain;

// Remove port information.
$Port = strpos($Domain, ':');
if (
$Port !== false) $Domain = substr($Domain, 0, $Port);
}

header('Set-Cookie: ' . rawurlencode($Name) . '=' . rawurlencode($Value)
. (empty(
$Expires) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $Expires) . ' GMT')
. (empty(
$Path) ? '' : '; path=' . $Path)
. (empty(
$Domain) ? '' : '; domain=' . $Domain)
. (!
$Secure ? '' : '; secure')
. (!
$HTTPOnly ? '' : '; HttpOnly'), false);
}
?>

Basically, if the domain parameter is supplied, it is converted to support a broader range of domains. This behavior may or may not be desireable (e.g. could be a security problem depending on the server) but it makes cookie handling oh-so-much-nicer (IMO).
To Top