PHP 5.4.31 Released

setcookie

(PHP 4, PHP 5)

setcookieEnvia um cookie

Descrição

bool setcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]] )

A função setcookie() define um cookie para ser enviado juntamente com o resto dos cabeçalhos HTTP. Como outros cabeçalhos (headers), os cookies devem ser enviados antes de qualquer saída do seu script (isso é uma restrição do protocolo). O que quer dizer que você deve colocar chamadas a essa função antes de qualquer saída, incluindo as tags <html> e <head> e também espaços em branco.

Uma vez que o cookie foi setado, ele pode ser acessado na próxima página através dos arrays $_COOKIE e $HTTP_COOKIE_VARS. Note que as superglobais como $_COOKIE estão disponíveis a partir do PHP 4.1.0. Os valores dos cookies também existem na variável $_REQUEST.

Parâmetros

Todos os argumentos, exceto o name, são opcionais. Você pode também colocar como argumento uma string vazia ("") para pular o argumento. Como o argumento expire é um inteiro, ele não pode ser escapado com uma string vazia, por isso utilize um zero (0) no lugar.

Veja a » RFC 6265 para ver como cada parâmetro de setcookie() funciona.

name

O nome do cookie.

value

O valor do cookie. Esse valor é guardado no computador do cliente; não guarde informação sensível. Supondo que o name seja 'nomedocookie', o valor pode ser lido través de $_COOKIE['nomedocookie']

expire

O tempo para o cookie expirar. Esse valor é uma timestamp Unix, portanto é o número de segundos desde a época (epoch). Em outras palavras, você provavelmente irá utilizar isso com a função time() mais o número de segundos que você quer que ele expire. Ou você pode utilizar a função mktime(). time()+60*60*24*30 irá configurar o cookie para expirar em 30 dias. Se configurado para 0, ou omitido, o cookie irá expirar ao fim da sessao (quando o navegador fechar).

Nota:

Você pode ver que o parâmetro expire recebe uma timestamp Unix, ao contrário do formato de data Wdy, DD-Mon-YYYY HH:MM:SS GMT, isso se dá porque o PHP faz essa conversão internamente.

path

O caminho no servidor aonde o cookie estará disponível. Se configurado para '/', o cookie estará dosponí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 domínio para qual o cookie estará disponível. Configurando o domínio para 'www.example.com' fará com que o cookie esteja disponível no subdomínio www e nos subdomínios superiores. Cookies disponíveis para um domínio inferior, como 'example.com' estarão disponíveis para subdomínios superiores, como 'www.example.com'. Browsers 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ó podera ser transimitido 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 browsers), mas essa informação é constantemente discutida. Foi adicionada no PHP 5.2.0. TRUE ou FALSE

Valor Retornado

Se existe 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.

Exemplos

Alguns exemplos para seguir de como enviar cookies:

Exemplo #1 Exemplo de setcookie() para enviar cookies

<?php
$value 
'alguma coisa de algum lugar';

setcookie("CookieTeste"$value);
setcookie("CookieTeste"$valuetime()+3600);  /* expira em 1 hora */
setcookie("CookieTeste"$valuetime()+3600"/~rasmus/"".example.com"1);
?>

Note que a porção do valor do cookie será automaticamente codificada com urlencode quando você enviar o cookie, e quando ele for recebido, será automaticamente decodificado e atribuido a uma variável com o mesmo nome do cookie. Se você não quer que isso aconteça, você pode utilizar no lugar a função setrawcookie() se você estiver utilizando o PHP 5. Para ver o conteúdo do nosso cookie de teste em um script, simplesmente utilize um dos exemplos abaixo:

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

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

Exemplo #2 Exemplo de setcookie() para deletar cookies

Quando estiver deletando um cookie, tenha certeza de que a data de expiração dele está no passado, para acionar o mecanismo de remoção do seu navegador. O exemplo a seguir mostra como deletar 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

Você pode também enviar cookies de array, utilizando a notação de array no nome dele. Isso tem o efeito de enviar tantos cookies quantos elementos houverem no array, mas quando o cookie for recebido todos os valores serão 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");

// Depois que a página recarregar, mostra eles
if (isset(
$_COOKIE['cookie'])) {
    foreach (
$_COOKIE['cookie'] as $nome => $valor) {
        echo "
$nome $valor <br />\n";
    }
}
?>

O exemplo acima irá imprimir:

tres : cookietres
dois : cookiedois
um : cookieum

Changelog

Versão Descrição
5.2.0 O parâmetro httponly foi adicionado.

Notas

Nota:

Você pode utilizar o output buffering para enviar saída antes de chamar essa função, com o custo de toda sua saída ser guardada em buffer até que você a envie. Você pode fazer isso chamando ob_start() e ob_end_flush() em seu script, ou configurando a diretiva output_buffering no seu php.ini ou arquivos de configuração do servidor.

Nota:

Se a diretiva register_globals estiver configurada como on então os valores dos cookies serão colocadas em variáveis. Em nossos exemplos acima, a variável $CookieTeste irá existir. É recomendado o uso de $_COOKIE.

Problemas comuns:

  • Os cookies não estarão disponíveis até o próximo carregamento da página a qual o cookie deverá estar visível. Para testar se um cookie foi enviado com sucesso, verifique o cookie no próximo carregamento da página antes que ele expire. O tempo para expirar é configurado via o parâmetro expira. Uma maneira boa de depurar a existência dos cookies é chamando a função print_r($_COOKIE);.
  • Os cookies devem ser deletados com os mesmos parâmetros com os quais foram configurados. Se o argumento valor for uma string vazia, ou FALSE, e todos os outros argumentos forem iguais a chamada anterior de setcookie, então o cookie com o nome especificado será deletado 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 você configurar um cookie com o valor FALSE será tentando deletar o cookie. Portanto evite utilizar valores booleanos. No lugar, utilize 0 para FALSE e 1 for TRUE.
  • Nomes de cookies podem ser configurados como arrays e estarão disponíves para seus scripts PHP como arrays mas cookies separados serão guardados no sistema do usuário. Considere 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 ele 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

add a note add a note

User Contributed Notes 49 notes

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

You can this:
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
up
5
bluewaterbob
7 years ago
if you are having problems seeing cookies sometimes or deleting cookies sometimes, despite following the advice below, make sure you are setting the cookie with the domain argument. Set it with the dot before the domain as the examples show: ".example.com".  I wasn't specifying the domain, and finally realized I was setting the cookie when the browser url had the http://www.example.com and later trying to delete it when the url didn't have the www. ie. http://example.com. This also caused the page to be unable to find the cookie when the www. wasn't in the domain.  (When you add the domain argument to the setcookie code that creates the cookie, make sure you also add it to the code that deletes the cookie.)
up
6
jdknock (at) gMaIl (dot) com
3 years ago
IE7 can have trouble with settings cookies that are embedded in an iframe. The problem lies with a W3C standard called Platform for Privacy Preferences or P3P for short.

To overcome, include the header:

header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');

before setting the cookie.
up
13
jonathan dot bergeron at rve dot ulaval dot ca
7 years ago
About the delete part, I found that Firefox only remove the cookie when you submit the same values for all parameters, except the date, which sould be in the past. Submiting blank values didn't work for me.

Example :
- set -

<?php setcookie( "name", "value", "future_timestamp", "path", "domain" ); ?>

- delete -
<?php setcookie( "name", "value", "past_timestamp", "path", "domain" ); ?>

Jonathan
up
6
Eric
4 years ago
The server my php code is running on has sessions disabled so I am forced to store a fair bit of arbitrary data in cookies.  Using array names was impractical and problematic, so I implemented a splitting routine.  I do not serialize any class instances, just arrays and simple objects.

In a nutshell, when setting a cookie value, I serialize it, gzcompress it, base64 encode it, break it into pieces and store it as a set of cookies.  To fetch the cookie value I get the named piece then iterate through piece names rebuilding the base64 data, then reverse the rest of the process.  The only other trick is deleting the pieces correctly.

Sessions are better, but if they are not available this is a viable alternative.  I chose gz over bz for compression because it looked faster with only slightly worse ratios.

Here is a simplified version of my implementation.  This is a good starting point but is not suitable for most uses.  For example, the domain and path are hard coded and no return values are checked for validity.

<?php
define
( 'COOKIE_PORTIONS' , '_piece_' );

function
clearpieces( $inKey , $inFirst ) {
   
$expire = time()-3600;
   
    for (
$index = $inFirst ; array_key_exists( $inKey.COOKIE_PORTIONS.$index , $_COOKIE ) ; $index += 1 ) {
       
setcookie( $inKey.COOKIE_PORTIONS.$index , '' , $expire , '/' , '' , 0 );
        unset(
$_COOKIE[$inKey.COOKIE_PORTIONS.$index] );
    }
}

function
clearcookie( $inKey ) {
   
clearpieces( $inKey , 1 );
   
setcookie( $inKey , '' , time()-3600 , '/' , '' , 0 );
    unset(
$_COOKIE[$inKey] );
}

function
storecookie( $inKey , $inValue , $inExpire ) {
   
$decode = serialize( $inValue );
   
$decode = gzcompress( $decode );
   
$decode = base64_encode( $decode );
   
   
$split = str_split( $decode , 4000 );//4k pieces
   
$count = count( $split );
   
    for (
$index = 0 ; $index < $count ; $index += 1 ) {
       
$result = setcookie( ( $index > 0 ) ? $inKey.COOKIE_PORTIONS.$index : $inKey , $split[$index] , $inExpire , '/' , '' , 0 );
    }
   
   
clearpieces( $inKey , $count );
}

function
fetchcookie( $inKey ) {
   
$decode = $_COOKIE[$inKey];
   
    for (
$index = 1 ; array_key_exists( $inKey.COOKIE_PORTIONS.$index , $_COOKIE ) ; $index += 1 ) {
       
$decode .= $_COOKIE[$inKey.COOKIE_PORTIONS.$index];
    }
   
   
$decode = base64_decode( $decode );
   
$decode = gzuncompress( $decode );
   
    return
unserialize( $decode );
}
?>
up
6
Carl V
9 years ago
If you want to delete all the cookies set by your domain, you may run the following:

<?php
$cookiesSet
= array_keys($_COOKIE);
for (
$x=0;$x<count($cookiesSet);$x++) setcookie($cookiesSet[$x],"",time()-1);
?>

Very useful when doing logout scripts and the cookie name may have changed (long story).
up
6
10 years ago
When using your cookies on a webserver that is not on the standard port 80, you should NOT include the :[port] in the "Cookie domain" parameter, since this would not be recognized correctly.
I had the issue working on a project that runs on multiple servers (development, production, etc.). One of the servers is running on a different port (together with other websites that run on the same server but on different ports).
up
3
stovenator at gmail dot com
7 years ago
If you are having issues with IE7 and setcookie(), be sure to verify that the cookie is set via http for http sites, and https for https site.

Also, if the time is incorrect on your server, IE7 will also disallow those cookies from being set.
up
3
terry at scribendi dot com
9 years ago
A few comments have suggested using serialize() to set object or array data into a cookie.  There are a couple of reasons to be carefull with that technique:

Security: If the cookie is human readable, then it is also fairly easy for end users to play around with it.  Wrapping your cookie setting and getting in an encryption routine will prevent tampering, and make sure that your cookies don't make any sense to any client-side exploits or other sites they get sent to thanks to browser bugs.

Bulk: If you serialize even a fairly simple class, then you get a lot of data.  Large cookies will make browser requests fat and slow, and some browsers have a limit on cookie size, so think about what data you really need to persist, and create __sleep() and __wakeup() methods to package the data into the shortest possible form.  You can get better and faster results when you write your own __sleep() and __wakup() to implode() or pack() your data, than by using zlib compress() on the serialized object.
up
3
MrXCol
3 years ago
If you're having problem with IE not accepting session cookies this could help:

It seems the IE (6, 7, 8 and 9) do not accept the part 'Expire=0' when setting a session cookie. To fix it just don't put any expire at all. The default behavior when the 'Expire' is not set is to set the cookie as a session one.

(Firefox doesn't complains, btw.)
up
5
Anonymous
7 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
2
paul nospam AT nospam sitepoint dot com
7 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
2
hansel at gretel dot com
7 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).
up
4
laffen
5 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
5
mkmohsinali at gmail dot com
3 years ago
#cookies.php
/*This code will demonstrate use of cookies with PHP
It is very easy to understand and is better for beginner to
understand and get idea about power of cookies when used
with PHP.Here we give user a form to choose colors he/she
likes for website and when he/she visits site again within one
hour his/her settings are saved and read from cookie
and he/she doesn't have to set the page color and page
text color again.You can change time from 3600
seconds to whatever you deem appropriate in your case.
if you don't understand anything please email me*/

<?php
#checking if form has been submitted
if (isset($_POST['submitted'])){
#if yes (form is submitted) assign values from POST array to variables
$newbgColor=$_POST['bgColor'];
$newtxtColor=$_POST['txtColor'];
#set cookies
setcookie("bgColor",$newbgColor,time()+3600);
setcookie("txtColor",$newtxtColor,time()+3600);

}
#in case user has come for first time and cookies are not set then
if ((!isset($_COOKIE['bgColor']) ) && (!isset($_COOKIE['txtColor']))){
$bgColor = "Black";
$txtColor="White";
}
#if cookies are set then use them
else{
$bgColor = $_COOKIE['bgColor'];
$txtColor = $_COOKIE['txtColor'];
}
?>
<!-- HTML Page-->
<html>
<body bgcolor="<?php echo $bgColor ?>" text="<?php echo $txtColor ?>">
<form action= "<?php echo $_SERVER['PHP_SELF']; ?>" method ="POST">
<p>Body Color:</p>
<select name=bgColor>
<option value ="Red">Red</option>
<option value ="Green" selected>Green</option>
<option value ="Blue">Blue</option>
<option value ="Yellow">Yellow</option>
<option value ="Black">Black</option>
<option value ="Brown">Brown</option>
<option value ="White">White</option>
</select>
<p>Text Color:</p>
<select name=txtColor>
<tion value ="Red">Red</option>
<option value ="Green" selected>Green</option>
<option value ="Blue">Blue</option>
<option value ="Yellow">Yellow</option>
<option value ="Black">Black</option>
<option value ="Brown">Brown</option>
<option value ="White">White</option>
</select>
<input type ="hidden" name="submitted" value="true"></br>
<input type="submit" value="remind">
</form>
</body>
</html>
up
5
bocian941 at pawno dot pl
3 years ago
My 2 functions to use "live cookies":

<?php
   
function SetCookieLive($name, $value='', $expire = 0, $path = '', $domain='', $secure=false, $httponly=false)
    {
       
$_COOKIE[$name] = $value;
        return
setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
    }

    function
RemoveCookieLive($name)
    {
        unset(
$_COOKIE[$name]);
        return
setcookie($name, NULL, -1);
    }
?>
up
3
jay at w3prodigy dot com
4 years ago
You can also delete cookies by supplying setcookie an empty value.

setcookie("w3p_cookie", "");
up
2
Anonymous
3 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
3
chris at styl dot ee
3 years ago
I was searching for a simple example of creating a cookie, storing a random number and updating it on refresh. I couldn't find one so I had to figure it out on my own....

- - - -
One thing to *NOTE* is technically you can't update a cookie, you can only overwrite it with a new one with the same name.

- - - -

This creates a random number, stores it in a cookie, then references it on refresh, checks for duplicates and does necessary correction, then stores it again, rinse and repeat...

<?php
ob_start
();
$MaxCount = 4;// set the max of the counter, in my tests "4" = (0,1,2,3) I adjusted below (+1) to get a "real" 4 (0,1,2,3,4) this is in reality 5 keys to humans, you can adjust script to eliminate "0", but my script makes use of the "0"

$random =(rand()%($MaxCount+1));//give me a random number limited by the max, adding "1" because computers start counting at "0"

if(!isset($_COOKIE['random'])){// check if random number cookie is not set
    //echo"not set";
   
setcookie('random', $random);//set the cookie for the first time
   
}else{
   
$lastRandom= $_COOKIE['random']; //hold the last number if it was set before
   
if($lastRandom == $random){//some logic to avoid repeats
    
if($random < $MaxCount){//if below max, add 1
       
$random++;
       
//echo "under the max, adding 1, ";   
   
}elseif($random >= ($MaxCount-1)){// if for some reason the random number is more than max or equal to it -1, and an additional -1 for max count in initial var (so in reality this -1 from intial max var, and -1 from $random which should be the same number)
           
$random--;
           
//echo "hit the max, subtracting 1, ";
       
}else{
       
$random++;
       
//echo "no case match, adding 1, ";   
       
}
   
//echo "(".$lastRandom.", ".$random. "), they matched initally - was it fixed?";
   
}else{
   
//echo "(".$lastRandom.", ".$random. "), they DO NOT match";
   
setcookie('random', $random);   
    }
   
//echo"is set: {$_COOKIE['random']}";
}

ob_end_flush();

?>
up
2
mike
7 years ago
Be careful of using the same cookie name in subdirectories. Setting a simple cookie

<?php setcookie("region", $_GET['set_region']); ?>

both in the root / and for instance in this case /admin/ will create 2 cookies with different paths. In reading the cookies back only the first one is read regardless of path.
up
1
gabe at fijiwebdesign dot com
7 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
3
ahmetantmen at msn dot com
7 years ago
You can be sure about the cookie files contents weren't changed.

<?php

$Seperator
= '--';
$uniqueID = 'Ju?hG&F0yh9?=/6*GVfd-d8u6f86hp';
$Data = 'Ahmet '.md5('123456789');

setcookie('VerifyUser', $Data.$Seperator.md5($Data.$uniqueID));

if (
$_COOKIE) {
  
$Cut = explode($Seperator, $_COOKIE['VerifyUser']);
   if (
md5($Cut[0].$uniqueID) === $Cut[1]) {
      
$_COOKIE['VerifyUser'] = $Cut[0];
   } else {
       die(
'Cookie data is invalid!!!');
   }
}

echo
$_COOKIE['VerifyUser'];

?>

Create a unique id for your site and create a hash with md5($Data.$uniqueID). Attacker can understant that it must be re-hash after change cookie content.
But doesn't. Because cannot guess your unique id. Seperate your hash and data with seperator and send that cookie. Control that hash of returned value and your unique id's is same returned hash. Otherwise you have to stop attack. Sorry for my poor english!
up
2
Bachsau
2 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
1
gareth at gw126 dot com
8 years ago
You can use cookies to prevent a browser refresh repeating some action from a form post... (providing the client is cookie enabled!)

<?php
//Flag up repeat actions (like credit card transaction, etc)
if(count($_POST)>0) {
   
$lastpost= isset($_COOKIE['lastpost']) ? $_COOKIE['lastpost'] : '';
    if(
$lastpost!=md5(serialize($_POST))) {
       
setcookie('lastpost', md5(serialize($_POST)));
       
$_POST['_REPEATED']=0;
    } else {
       
$_POST['_REPEATED']=1;
    }
}

//At this point, if $_POST['_REPEATED']==1, then  the user
//has hit the refresh button; so don't do any actions that you don't
//want to repeat!
?>

Hope that helps :)

Gareth
up
0
ellert at vankoperen dot nl
20 days 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
0
RC
3 years ago
For those of your banging your head as to why a cookie is not present when Internet Explorer 6 prints, the explanation is quite interesting. After a bit of investigation, a cookie with an expiration time other than 0 fails to be passed from IE6 to the server when printing. A cookie with an expiration time of 0 is sent.

Therefore:

setcookie("TestCookie", $value, time()+3600); //will not be sent from Print / Print Preview in IE6

setcookie("TestCookie", $value, 0); //will be sent from Print / Print Preview in IE6

I'll let everyone figure out who's bright idea it was to not send normal expiring cookies when printing in IE6...
up
0
cwillard at fastmail dot fm
6 years ago
If you're looking to set multiple values in your cookie (rather than setting multiple cookies) you might find these useful.

<?php
function build_cookie($var_array) {
  if (
is_array($var_array)) {
    foreach (
$var_array as $index => $data) {
     
$out.= ($data!="") ? $index."=".$data."|" : "";
    }
  }
  return
rtrim($out,"|");
}

function
break_cookie ($cookie_string) {
 
$array=explode("|",$cookie_string);
  foreach (
$array as $i=>$stuff) {
   
$stuff=explode("=",$stuff);
   
$array[$stuff[0]]=$stuff[1];
    unset(
$array[$i]);
  }
  return
$array;
}
?>
Hopefully someone finds these useful.
up
0
Anonymous
7 years ago
if you only want to do something once per unique visitor, you can test if a cookie is set, and if not, set the cookie and perform the action. This being the poorman's version, it has a problem, where if a user is blocking cookies they will appear as a first time visitor each time. What you can do to avoid this is to set a test cookie first and check that it exists. If it exists, then check to see if your second cookie has been set. If the first one is set, but the second isn't, then you know this is a first time visitor.
up
0
Anonymous
7 years ago
If you ever find yourself in a situation where you need to overwrite a non-PHP application's session cookie, you can do that with the following line:

<?php
header
("Set-Cookie: SIDNAME=$overwrite; path=/; secure");
?>

I couldn't get setcookie() to do this for all major web browsers, but manually sending the header did the trick. Note: Remove secure if you aren't mandating SSL connections.
up
0
apex at xepa dot nl
10 years ago
Note on setting cookies allowing access to sites:

If you are not using something "personal" from the computer that you are sending the cookie too watch out.  Via javascript it is possible to steal cookies from other users.  Thus allowing the stealer to login to your site as another user that might not have access otherwise.  Try to add something like the user's ip in the cookie and allowing access from that ip only with the stored cookie data.

[Editor's note: ... or simply use sessions. You can't be sure that the visitor will use the same IP the next visit. Not even on the next request (thanks to proxy servers)]
up
0
dave at fubra dot com
10 years ago
There are several characters that dont work correctly if part of the cookie name, I in particular ran into problems using = as part of the cookie name ie/

<?php setcookie('dE4fR=', $foo); ?>

this was as a result of base64_encode() ing a variable to use as the name. The cookie was being set fine but the = is stored as a little square character in the cookie which prevent proper retreival.

The solution for me was to use md5() instead of base64_encode() but any other method which avoids the = sign should also solve the problem
up
-2
adruff at gmail dot com
7 years ago
If you intend to use persistent cookies (vice session cookies that are deleted when the browser is closed) be aware:
1) Firefox appears to require that you include all paramaters, or it will ignore the expiration and treat the cookie as a session cookie
2) My version of firefox (1.5.0.6) defaults to 'keep cookies until i close firefox' , which essentially makes every cookie a session cookie. This of course sucks for devs, but i suppose is supposed to be a security feature for the end user. If the user wants to configure firefox to respect the expiration date and retain cookies beyond the session, the user must change it to 'keep cookies until they expire'.
up
-2
Alchaemist
9 years ago
setcookie + header Location + IIS 5 = Trouble

It took me a long time to figure out what was causing a missing cookie in one system while it worked perfectly in another...

See this one: http://support.microsoft.com/kb/q176113/

In short, this WILL NEVER WORK IN IIS 5:
<?php
header
("Pragma: no-cache");
header('Location: http://www.example.com/');
setcookie('AA','1',0,'/');
setcookie('BB','2',time() + 24 * 3600,'/');
?>

You will ONLY get the Location Header, everything else will be "cut out" by IIS 5 CGI implementation.

Solutions:
1- Migrate to Apache/IIS6/Whatever
2- Use a Non Parsed Header Script (nph-*.php)
3- Try with header('Refresh: 0; $URL');

I hope this helps somebody not to spend hours knocking his/her head.

Alchaemist
up
-2
vanclute at gmail dot com
2 years ago
I have been tearing my hair out wondering why a cookie would not delete.  Despite countless discussions of reasons this can happen all over the internet, none of them addresses my case.  Here is what was happening:

My cookies have been formed kindof as an array, and the name of the cookie to be deleted is being passed in a variable, so I was using this to attempt to delete the cookie (stripped to the minimum for simplicity of the example):

<?php
    setcookie
("$cookiename[id]");
?>

But it simply would not work.  Ultimately what DID work was this:

<?php
    setcookie
($cookiename."[id]");
?>

So I had to concatenate the variable to the "element id" and then the cookies deleted without any issue.

I hope this saves someone else from a sleepless night!!

Jonathan
up
-1
danielpopescu93 at gmail dot com
1 year ago
Hei, so here is what problem I had, maybe it will help someone in the future:
I couldn't delete a cookie, not even set it a different value. I think that is because it had a name following the rule FirstSecondThird. So it had uppercase letters.
After I modified the name everithing worked.

Another note:
Just for safety you should put what you want to put in the cookie in a var first.
up
-2
herrkampfgarten at gmail dot com
1 year ago
Please note that setting the expiry to some timestamp in the past is a common way to get rid of a cookie. However, depending on the value you might set to "invalidate" a cookie immediately, this may pose a threat to the privacy of your user's data, especially when it comes to session cookies.

If you write "0" and "expire-in-the-past" into a session cookie, it remains on the client-side until the clean-up mechanism of the browser hits. (That might be anything from no-time to a very long time. I'm not even thinking of app-based mobile browsers that won't close properly or do their best to ignore standards and RFCs and stuff...)

So, if you have sufficiently messed up your ways of picking up existing session IDs and write-closing their data to your server, the session's data might move from file "sess_(random)" to "sess_0", because that is exactly the identifier that is referred in the cookie.

From now on (at least until your server decides to clean up) there is data laying open wide to anyone requesting the session "0". Which may happen by accident (i.e. another user gains an own "0"-cookie) or malice (i.e. forgery).

Long story short, ALWAYS use an empty string instead of a "0" value for invalidating a session cookie.
up
-2
dbessoudo at gmail dot com
4 years ago
setcookie - value = "deleted" on IE

  setcookie(session_name(), '', time()-42000, '/');

When "setcookie" is passed an empty value (ie, ''), it changes the value to the string "deleted" and sets the date to exactly one year and one second in the past, ignoring the expiration parameter.*

So, I'm guessing that if a client machine has its time set to more than a year in the past or if the browser is somehow broken, then a site visitor could potentially send a PHPSESSID with a value of "deleted".  This will cause PHP to create a "sess_deleted" file in the sessions directory.

In my case, I was seeing several incidents per minute, with each user clobbering the other's session data causing all kinds of security and identity issues.  Two changes seemed to have solved the problem:

1) Use session_id() in place of '' in setcookie, as well as pick a date that's far in the past (in this case Jan 1, 1970, 8:00:01AM):

    setcookie(session_name(), session_id(), 1, '/');

2) Use session_regenerate_id() when logging a user in or otherwise changing their authority level.

Hope this helps somebody.

Rob

* Here is the relevant code in head.c:

    if (value && value_len == 0) {
        /*                                                                                                                                                                                                     
         * MSIE doesn't delete a cookie when you set it to a null value                                                                                                                                        
         * so in order to force cookies to be deleted, even on MSIE, we                                                                                                                                        
         * pick an expiry date 1 year and 1 second in the past                                                                                                                                                 
         */
        time_t t = time(NULL) - 31536001;
        dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC);
        sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);
up
-1
soeren dot spreng at gmail dot com
6 years ago
Beware: The Internet Explorer doesn't accept Cookies with an expiretime, which is to long. time() + time() for example doesn't work and the Cookie won't be created!
up
-3
jacobkamphansen at gmail dot com
3 years ago
I've been pulling my hair for a couple of minutes (read: hours) and finally figured out why setcookie in my case, returned the "headers already sent"-error:

The file in question was orignally saved as ANSI in Notepad and worked flawlessly, but when saved with UTF-8-encoding, it didn't work. So after trying phpDesigner 7, I was able to both save the file in UTF-8 AND remove the BOM (byte-order-mark which is output BEFORE the cookie is set and thereby fails everything).
up
-1
Marcin Wiazowski
7 years ago
'session.cookie_domain' should be set to empty string for all local domain names, not only for 'localhost' (but should not be empty for local IP addresses):

<?php
ini_set
('session.cookie_domain', (strpos($_SERVER['HTTP_HOST'],'.') !== false) ? $_SERVER['HTTP_HOST'] : '');
?>
up
-1
simon at ruderich dot com
8 years ago
If you want to delete a session cookie, you can do it with this code:

<?php
  session_start
();

 
// many code

 
$sessionName = session_name();
 
$sessionCookie = session_get_cookie_params();

 
session_destroy();

 
setcookie($sessionName, false, $sessionCookie['lifetime'], $sessionCookie['path'], $sessionCookie['domain'], $sessionCookie['secure']);
?>

This works also well if the session cookie params or the session name were changed.
up
-1
soreman at abv dot bg
11 years ago
If you experience problems on Microsoft Information Server (IIS) when setting a cookie via PHP and when PHP is running as a CGI binary it is not setting the cookie. After spending many hours on what the problem is here is what happens:

When you invoke setcookie and redirect to another page you will not have your cookie set, because it seems that IIS doesn't set the cookie unless you actually send some contents to the browser. Therefore if you want to set a cookie and then redirect to another page you will have to do the redirection via JavaScript and/or HTML if you want your script to work on IIS.
up
-1
mleer at sp dot nl
11 years ago
P3P is a good idea. But.
IE 6 features an inadequate definition of third party cookies.
If your site is hosted on server A and your PHP stuff is coming in a framesetting from server B your setcookie-attempts will be blocked when default privacy settings are deployed. Your secondparty-cookie will be regarded as a thirdparty-cookie.

So what you do is not read the P3P-Internet Explorer 6-manual at MS but send a header like

<?php
header
('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"');
?>

before doing the setcookie-thing. This will enable your cookie to survive any IE-6 privacy settings.

You won't do this if you're working for some doubleclick institution, because if you do, you... you...well... you are not a very nice person!
up
-2
karamfil dot pc at gmail dot com
3 years ago
Beware of underscores in the hostname, because IE won't save cookies.
up
-2
php at gigadepot dot com
6 years ago
If you use a multiple cookie name with the function bellow

example :

createcookie("member[name]","jack");

don't work with array

error with "rawurlencode($name)"

I'm use : createcookie(array('member'=>'name'),'jack');

<?php
createCookie
($name, $value='', $maxage=0, $path='',$domain='', $secure=false, $HTTPOnly=false)
    {
        if(
is_array($name))
        {
            list(
$k,$v)    =    each($name);

               
$name    =    $k.'['.$v.']';

        }
       
$ob = ini_get('output_buffering');
       
// Abort the method if headers have already been sent, except when output buffering has been enabled
       
if ( headers_sent() && (bool) $ob === false || strtolower($ob) == 'off' )
            return
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);
           
// Add the dot prefix to ensure compatibility with subdomains
           
if ( substr($domain, 0, 1) != '.' ) $domain = '.'.$domain;
           
// Remove port information.
           
$port = strpos($domain, ':');
            if (
$port !== false ) $domain = substr($domain, 0, $port);
        }
       
// Prevent "headers already sent" error with utf8 support (BOM)
        //if ( utf8_support ) header('Content-Type: text/html; charset=utf-8');
       
if(is_array($name))
        {
           
header('Set-Cookie: '.$name.'='.rawurlencode($value)
                                    .(empty(
$domain) ? '' : '; Domain='.$domain)
                                    .(empty(
$maxage) ? '' : '; Max-Age='.$maxage)
                                    .(empty(
$path) ? '' : '; Path='.$path)
                                    .(!
$secure ? '' : '; Secure')
                                    .(!
$HTTPOnly ? '' : '; HttpOnly'), false);
        }else{
           
header('Set-Cookie: '.rawurlencode($name).'='.rawurlencode($value)
                                    .(empty(
$domain) ? '' : '; Domain='.$domain)
                                    .(empty(
$maxage) ? '' : '; Max-Age='.$maxage)
                                    .(empty(
$path) ? '' : '; Path='.$path)
                                    .(!
$secure ? '' : '; Secure')
                                    .(!
$HTTPOnly ? '' : '; HttpOnly'), false);
        }
        return
true;
    }
?>
up
-2
isooik at gmail-antispam dot com
6 years ago
Here's a more advanced version of the php setcookie() alternative function:

<?php

   
/**
     * A better alternative (RFC 2109 compatible) to the php setcookie() function
     *
     * @param string Name of the cookie
     * @param string Value of the cookie
     * @param int Lifetime of the cookie
     * @param string Path where the cookie can be used
     * @param string Domain which can read the cookie
     * @param bool Secure mode?
     * @param bool Only allow HTTP usage?
     * @return bool True or false whether the method has successfully run
     */
   
function createCookie($name, $value='', $maxage=0, $path='', $domain='', $secure=false, $HTTPOnly=false)
    {
       
$ob = ini_get('output_buffering');

       
// Abort the method if headers have already been sent, except when output buffering has been enabled
       
if ( headers_sent() && (bool) $ob === false || strtolower($ob) == 'off' )
            return
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);
           
// Add the dot prefix to ensure compatibility with subdomains
           
if ( substr($domain, 0, 1) != '.' ) $domain = '.'.$domain;

           
// Remove port information.
           
$port = strpos($domain, ':');

            if (
$port !== false ) $domain = substr($domain, 0, $port);
        }

       
// Prevent "headers already sent" error with utf8 support (BOM)
        //if ( utf8_support ) header('Content-Type: text/html; charset=utf-8');

       
header('Set-Cookie: '.rawurlencode($name).'='.rawurlencode($value)
                                    .(empty(
$domain) ? '' : '; Domain='.$domain)
                                    .(empty(
$maxage) ? '' : '; Max-Age='.$maxage)
                                    .(empty(
$path) ? '' : '; Path='.$path)
                                    .(!
$secure ? '' : '; Secure')
                                    .(!
$HTTPOnly ? '' : '; HttpOnly'), false);
        return
true;
    }

?>

Regards,
Isaak
up
-2
mikeh at view22 dot com
6 years ago
Observed: session cookies were expiring even though the session was still active.  (To test, set a cookie expiry of 5 seconds and keep hitting the page every second.  The session will expire and create a new SESSID after 5 seconds despite the fact that you hit the page only a second ago.)

Calling this function before starting the session fixed it.  It copies the cookie contents back to itself while forcing an update to the expiry time in the cookie.

<?php
function FreshenSessionCookie($lifetimeSeconds, $cookieName = 'PHPSESSID')
{
    if (isset(
$_COOKIE[$cookieName]))
        {
       
$data = $_COOKIE[$cookieName];
       
$timeout = time()+$lifetimeSeconds;
       
setcookie($cookieName, $data$timeout);
        }
}
?>
up
-2
kurtubba at gmail dot com
7 years ago
When setting a top level domain ex ".mydomain.com" you must add the secure arg so it should look like

<?php
setcookie
("TestCookie", $value, time()+3600, "/", ".example.com", 0);
?>


ignoring the secure arg makes IE ignores the cookie
to get the top level domain use

<?php
$myDomain
= ereg_replace('^[^\.]*\.([^\.]*)\.(.*)$', '\1.\2',$_SERVER['HTTP_HOST']);
?>


to avoid localhost switch use

<?php
$phpCkDmn
= $_SERVER['HTTP_HOST'] != "localhost" ? $myDomain : false;
?>
up
-3
jbouvet at absolunet dot com
9 months ago
When deleting a cookie that was set in Javascript, add the path to the setcookie function, like so :

setCookie('cookie_name', '', time()-3600, '/');
To Top