PHP Doku:: Sendet ein Cookie - function.setcookie.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzSonstige DiensteNetworkNetzwerk-Funktionensetcookie

Ein Service von Reinhard Neidl - Webprogrammierung.

Netzwerk-Funktionen

<<pfsockopen

setrawcookie>>

setcookie

(PHP 4, PHP 5)

setcookieSendet ein Cookie

Beschreibung

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

setcookie() definiert ein mit den HTTP Header-Informationen zu übertragendes Cookie. Wie andere Header auch, müssen Cookies vor jeglicher Ausgabe Ihres Skriptes gesendet werden (dies ist eine Einschränkung des Protokolls). Das bedeutet, dass Sie diese Funktion aufrufen müssen, bevor Sie eine Ausgabe, dazu zählen auch <html>- oder <head>-Tags sowie jede Art von Whitespaces, übermitteln.

Sind die Cookies einmal gesetzt, können Sie beim nächsten Seitenaufruf anhand der $_COOKIE oder $HTTP_COOKIE_VARS Arrays auf diese zugreifen. Beachten Sie, dass die Superglobals wie $_COOKIE seit PHP 4.1.0 verfügbar sind. Die Cookie-Werte stehen auch in $_REQUEST.

Parameter-Liste

Alle Argumente außer name sind optional. Sie können ein Argument auch mit einem leeren String ("") ersetzen, wenn Sie es übergehen wollen. Da der expire-Parameter einen Integer-Wert darstellt, kann er nicht durch die Angabe eines Leerstrings übersprungen werden, verwenden Sie daher statt dessen die Null (0).

Lesen Sie die » Netscape cookie specification für die spezifische Funktionsweise der einzelnen setcookie()-Parameter.

name

Der Name des Cookies.

value

Der Wert des Cookies. Dieser Wert wird auf dem Computer des Benutzers gespeichert, speichern Sie deshalb darin keine sensiblen Informationen. Angenommen der Parameter name ist 'cookiename', so erhält man seinen Wert mittels $_COOKIE['cookiename'].

expire

Der Zeitpunkt, an dem das Cookie ungültig wird. Dies ist ein Unix Timestamp, also die Anzahl Sekunden seit Beginn der Epoche. Mit anderen Worten, Sie werden diesen Wert wahrscheinlich mittels der Funktion time() plus der Anzahl Sekunden bis zum gewünschten Ablauf des Cookies setzen. Sie könnten aber auch mktime() verwenden. time()+60*60*24*30 wird das Cookie in 30 Tagen ablaufen lassen. Hat der Parameter den Wert 0 oder ist er nicht gesetzt, verfällt das Cookie am Ende der Session (wenn der Browser geschlossen wird).

Hinweis:

Beachten Sie, dass der expire-Parameter einen Unix-Timestamp enthält, im Gegensatz zum Datumsformat Wdy, DD-Mon-YYYY HH:MM:SS GMT. Die Konvertierung wird von PHP intern durchgeführt.

expire wird mit der lokalen Zeit des Clients verglichen, da diese von der Server-Zeit differieren kann.

path

Der Pfad auf dem Server, für welchen das Cookie verfügbar sein wird. Ist er auf '/' gesetzt, wird das Cookie innerhalb der gesamten domain verfügbar. Ist er auf '/foo/' gesetzt, wird das Cookie nur innerhalb des Verzeichnisses /foo/ sowie allen Unterverzeichnissen wie z.B. /foo/bar/ der domain verfügbar. Der Standardwert ist das aktuelle Verzeichnis, in dem das Cookie gesetzt wurde.

domain

Die Domain, der das Cookie zur Verfügung steht. Um das Cookie für alle Subdomains von example.com verfügbar zu machen, setzen Sie es auf '.example.com'. Der . ist zwar nicht erforderlich, macht die Angabe aber zu mehr Browsern kompatibel. Ein Setzen auf www.example.com macht das Cookie nur in der Subdomain www verfügbar. Weitere Details hierzu finden Sie in der » Spezifikation.

secure

Gibt an, dass das Cookie vom Client nur über eine sichere HTTPS-Verbindung übertragen werden soll. Ist der Wert auf TRUE gesetzt, wird das Cookie nur gesendet, wenn eine sichere Verbindung besteht. Auf der Serverseite muss der Programmierer selbst darauf achten, dass entsprechende Cookies über eine sichere Verbindung gesendet werden (z.B. unter Berücksichtigung von $_SERVER["HTTPS"]).

httponly

Wenn auf TRUE gesetzt, ist das Cookie nur via HTTP-Protokoll zugreifbar. Das bedeutet, dass das Cookie nicht mehr für Skriptsprachen wie JavaScript auslesbar/veränderbar ist. Diese Einstellung kann eine effektive Hilfe sein, um Identitätsdiebstahl per XSS-Angriff zu vermindern (allerdings wird dies nicht von allen Browsern unterstützt). Hinzugefügt in PHP 5.2.0. TRUE oder FALSE

Rückgabewerte

Erfolgt eine Ausgabe vor dem Aufruf dieser Funktion, wird setcookie() fehlschlagen und FALSE zurückgeben. Wenn setcookie() erfolgreich durchgeführt wird, wird TRUE zurückgegeben. Dies sagt jedoch nichts darüber aus, ob der Benutzer das Cookie auch akzeptiert hat.

Beispiele

Einige Beispiele, wie Cookies gesetzt werden:

Beispiel #1 setcookie()-Beispiele:

<?php
$value 
'irgendetwas von irgendwo';

setcookie("TestCookie"$value);
setcookie("TestCookie"$valuetime()+3600);  /* verfällt in 1 Stunde */
setcookie("TestCookie"$valuetime()+3600"/~rasmus/"".example.com"1);
?>

Beachten Sie, dass der Wertebereich des Cookies automatisch URL-konform kodiert (urlencoded) wird, sobald Sie das Cookie senden, und es beim Erhalt automatisch dekodiert und einer Variablen zugewiesen wird, die den selben Namen wie das Cookie trägt. Wenn Sie dies nicht möchten, können Sie stattdessen setrawcookie() verwenden, wenn sie PHP 5 nutzen. Um die Inhalte unseres Test-Cookies in einem Skript sichtbar zu machen, verwenden Sie einfach eines der folgenden Beispiele:

<?php
// ein bestimmtes Cookie ausgeben
echo $_COOKIE["TestCookie"];
echo 
$HTTP_COOKIE_VARS["TestCookie"];

// Ein anderer Weg zu Debuggen/Testen ist, alle Cookies anzuzeigen
print_r($_COOKIE);
?>

Beispiel #2 setcookie()-Beispiele zum Löschen

Beim Löschen eines Cookies sollten Sie sicherstellen, dass das Verfallsdatum in der Vergangenheit liegt, um den Mechanismus zum Löschen des Cookies im Browser auszulösen. Die folgenden Beispiele zeigen, wie die im vorigen Beispiel gesendeten Cookies wieder gelöscht werden:

<?php
// Setzen des Verfalls-Zeitpunktes auf 1 Stunde in der Vergangenheit
setcookie ("TestCookie"""time() - 3600);
setcookie ("TestCookie"""time() - 3600"/~rasmus/"".example.com"1);
?>

Beispiel #3 setcookie() und Arrays

Sie können auch ein Array von Cookies setzen, in dem Sie die Array-Schreibweise im Cookienamen verwenden. Dadurch werden so viele Cookies gesetzt, wie Ihr Array Elemente hat. Sobald das Cookie aber von Ihrem Skript gelesen wird, werden alle Werte in ein einziges Array mit dem Cookienamen eingelesen:

<?php
// Setzen der Cookies
setcookie ("cookie[three]""cookiethree");
setcookie ("cookie[two]""cookietwo");
setcookie ("cookie[one]""cookieone");

// Nach dem Neuladen der Seite wieder ausgeben
if (isset($_COOKIE['cookie'])) {
    foreach (
$_COOKIE['cookie'] as $name => $value) {
        echo 
"$name : $value <br />\n";
    }
}
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

three : cookiethree
two : cookietwo
one : cookieone

Changelog

Version Beschreibung
5.2.0 Der httponly-Parameter wurde hinzugefügt.

Anmerkungen

Hinweis:

Sie können den Ausgabepuffer verwenden, um Ausgaben vor dem Aufruf dieser Funktion duchführen zu können. Dies hat allerdings zur Folge, dass alle Ihre Ausgaben zum Browser am Server zwischengespeichert werden, bis Sie diese senden. Sie können dies in Ihrem Skript mittels der Funktionen ob_start() und ob_end_flush() oder mittels der Konfigurationseinstellung output_buffering in Ihrer php.ini mitteilen, oder Sie ändern entsprechende Konfigurationseinstellungen am Server.

Hinweis:

Ist die PHP-Direktive register_globals auf on gesetzt, stehen die Cookies auch als eigene Variablen zur Verfügung. In den nachstehenden Beispielen wird $TextCookie also existieren. Es ist jedoch dringend empfohlen, $_COOKIE zu verwenden.

Häufige Probleme:

  • Cookies werden nicht sichtbar, bevor nicht eine Seite geladen wird, für die das Cookie sichtbar sein soll. Um zu testen, ob ein Cookie erfolgreich gesetzt wurde, prüfen Sie noch vor der Ablaufzeit auf der nächsten geladenen Seite, ob das Cookie vorhanden ist. Die Ablaufzeit wird mittels des Parameters expire gesetzt. Eine gute Möglichkeit, die Existenz von Cookies zu prüfen, ist einfach print_r($_COOKIE); aufzurufen.
  • Cookies müssen mit den selben Parametern gelöscht werden, mit denen sie gesetzt wurden. Ist der value-Parameter ein leerer String oder FALSE und alle anderen Werte entsprechen dem früheren Aufruf von setcookie, wird das Cookie mit dem angegebenen Namen vom Client gelöscht. Die wird intern ausgeführt, indem der Wert auf 'deleted' und die Verfallszeit auf ein Jahr in der Vergangenheit gesetzt wird.
  • Da beim Setzen eines Cookies mit dem Value FALSE versucht wird, das entsprechende Cookie zu löschen, sollten Sie keine boolschen Werte verwenden. Nutzen Sie statt dessen 0 für FALSE und 1 für TRUE.
  • Namen von Cookies können auch als Arraynamen gesetzt werden und stehen dann in Ihren Skripten als Arrays zu Verfügung, während sie auf dem System des Benutzers als separate Cookies abgespeichert werden. Erwägen Sie den Einsatz von explode(), um ein ein Cookie mit mehreren Namen und Werten zu setzen. Es ist nicht empfehlenswert, zu diesem Zweck serialize() einzusetzen, da hieraus Sicherheitslöcher erwachsen können.

Mehrfache Aufrufe von setcookie() werden in der Reihenfolge ihres Aufrufs ausgeführt.

Siehe auch


71 BenutzerBeiträge:
- Beiträge aktualisieren...
karamfil dot pc at gmail dot com
29.09.2010 14:10
Beware of underscores in the hostname, because IE won't save cookies.
RC
24.09.2010 16:50
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...
Anonymous
10.09.2010 12:20
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.
Turion
18.08.2010 15:05
For some reason once I set $path = '/', the cookies won't set unless I also specify $domain = ''....

Hope this helps somebody...
matt at jadu dot co dot uk
22.07.2010 0:08
If you are having problems with Internet Explorer not setting a cookie but Firefox will set the cookie, ensure that the date on your server is todays date and time and not a date in past!
danjr33 AT [google]mail.com
26.05.2010 1:04
I haven't seen any notes yet on this, so I wanted to give an example of setting a cookie and having the value available BEFORE you reload the page.
First, a disclaimer: this is only a workaround and it does not verify that the cookie was properly saved.

In some cases, it may be important to be able to access a cookie on the same page load. For example for my website I was using $_COOKIE['language'] to store and check the current interface language for the user. When this was changed I needed to use the new value on the SAME page load, and I didn't want to add a conditional statement to the later code.

This function is exactly identical to setcookie() except that it also sets $_COOKIE['cookiename'] to "cookievalue" and that will then be available on the same page load.

<?php
function setcookielive($name, $value='', $expire=0, $path='', $domain='', $secure=false, $httponly=false) {
   
//set a cookie as usual, but ALSO add it to $_COOKIE so the current page load has access
   
$_COOKIE[$name] = $value;
    return
setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
}
?>
jay at w3prodigy dot com
17.05.2010 21:31
You can also delete cookies by supplying setcookie an empty value.

setcookie("w3p_cookie", "");
jay at w3prodigy dot com
26.03.2010 16:38
To avoid the browser delay when working with cookies, you can create your cookie during the initialization process of your web site. If someone visits *any* page of your site, you should create that cookie with a default value after checking for the default value. Later, when you're working with the cookie, set it to what you need it to and it will be available on the next page the user visits.

This helps avoid forcing a browser reload on the client-side. A more refined method of working with cookies is to use my example above and then interact with the cookies using javascript.

To review:

Perform a conditional check to ensure the cookie does not exist and create it with a controlled default value. (You can later check for the default value when adding meaningful data)

<?php
$cookie_name
= "mytestcookie";
if( !isset(
$_COOKIE[$cookie_name]) && empty($_COOKIE[$cookie_name]) )
       
setcookie("$cookie_name", 0, 0, "/");
?>

The cookie "mytestcookie" is now accessibly readable and writeable.
nospam at oneillsoftware dot com dot au
17.03.2010 11:48
A note on setting cookie expiry times, particularly example #2 in which an attempt is made to delete the cookie by setting the expiry to 1 hour (3600 seconds) in the past.

The function <? time(); ?> returns the current LOCAL time on the server.

Suppose a server is located in New York with a UTC offset of -4. A client connecting from say Australia which has a UTC offset of +10 is 14 hours into the future from the point of view of the server in NY. If the American server attempts to set a session cookie which expires in say 1 hour, this would be interpreted by the client in Australia as a time 13 hours in the past. Naturally, the cookie is deleted on arrival and (depending on the script) the user might never be able to get past the login-correct page.

Now looking at the inverse example:

Suppose a server is located in Australia with a UTC offset of +10. A client connecting from New York with an offset of UTC-4 is 14 hours in the past as viewed from the Australian server.

If the Australian server attempts to clear a cookie as in example #2, like so:
<?
setcookie
("TestCookie", "", time() - 3600);
?>

the client will receive a time that is 13 hours into the FUTURE, and as a result, the cookie will not be cleared.

This is a potential security risk if sensitive (which really shouldn't be there in the first place...) or session data (which should be cleared on the server) is left in the cookie.

A good minimum value for deleting cookies that takes into account all timezones is 25 hours in the past (3600 * 25), rather than 3600.

Of course this would all be a lot easier if every browser was guaranteed to implement cookie expiration in UTC.
Hjalmar W
17.02.2010 12:48
When setting a cookie on a page that redirects, the cookie must be set after the call to header('Location: ....');

Such as:

<?php
header
('Location: http://www.example.com/');
setcookie('asite', $site, time()+60*60, '/', 'site.com');
?>
dbessoudo at gmail dot com
2.11.2009 17:58
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);
Eric
2.11.2009 7:57
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 );
}
?>
Anonymous
13.10.2009 8:31
After 2 hours of head scratching, I finally came across a PHP bug filed in 2002 about sending multiple Set-Cookie headers.
This may be a no-brainer to some, but make sure you set the 2nd param of header() to false if you wish to send multiple Set-Cookie headers to the browser, otherwise only the last Set-Cookie header will exist.
bluebike
10.10.2009 22:09
If you want your cookie to persist indefinitely, use pow(2,31)-1 as the expires value. That seems to be the largest value that is accepted.
LexyFivethousandTwothousandTwo at yahoo dot com
24.09.2009 2:42
If your isset($_COOKIE['cookieName']) call fails even though
the setcookie("cookieName", $cookieValue, time(),..)  returned
success, try replacing the timeout value with "0".  I just spent
an entire day on this strange problem.  I am using IE8. This
same call worked OK in the past with a timeout value of
time() + 360.  Anyway, changing it to "0" fixed the problem.

--Alex.
jah
20.09.2009 23:29
As <info at daniel-marschall dot de> points out, firefox will prepend a period (full-stop) to the domain value if the period is not already present.
This is because firefox expects the domain parameter value, if present, to be a domain name and not a host name.

So using setcookie() with a domain value of www.example.com is not correct if www is a host name.
If you want to restrict the cookie to a single host, supply the domain parameter as an empty string, for example (note the rightmost parameter):

<?php
setcookie
("TestCookie", "SomeValue", time()+3600, "/~rasmus/", "");
?>
info at daniel-marschall dot de
10.08.2009 16:16
Be careful when setting a domain value. The browsers have curious results (I tested with FireFox 3 only!).

If session.cookie_domain is "", then your browser will probably make the cookie only available for your domain "www.example.com". That's secure since subdomains probably cannot access the cookie.

If the session.cookie_domain has a value, for example "www.example.com", all browsers which are according to the RFC, will add a "." prefix to the domain. So "www.example.com" will be converted to ".www.example.com" by the browser. Now the cookie is not as secure as the cookie above since it is also accessable at subdomains.

Strange...
doricee at yahoo dot com
16.06.2009 6:15
When checking for whitespace make sure to check for a byte order mark.  Many text editors hide this char and it will cause errors with setcookie.

<?php setcookie("test", "cookietest");?>

<U+FEFF><?php setcookie("test", "cookietest");?>

http://en.wikipedia.org/wiki/Byte-order_mark
jesdisciple{ at t}gmail{d dot t}com
14.06.2009 2:41
For those who are writing their own replacement functions to comply with RFC 2109 / 2965 (and the PHP maintainers), note that your Max-Age value should technically be ignored, or at best treated as an ordinary value, unless you set Version=1.
laffen
27.05.2009 10:49
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

?>
Arthur Lui
23.05.2009 20:52
Also note that you should specify the path as '/' if you want the cookie to apply to the entire site, especially if the location of the file where you create the cookies isn't at the root.

The file that created the cookies was /assets/php/login.php and was creating cookies for the path "/assets/php/" only so it drove me nuts when I went to the homepage and the cookie wasn't accessible from there.
kyle [dot] florence [@t] gmail [dot] com
1.05.2009 21:00
Here is a static Cookie wrapper class that you may find helpful:
http://pastebin.com/f10a7bcba

Example usage:

<?php
// Basic usage
Cookie::set('testcookie', 'test');
print(
Cookie::get('testcookie'));

// You can set 'array' cookies in two different ways:
Cookie::set('array[one]', 'item one');
Cookie::set(array('array' => 'two'), 'item two');

// Likewise, you can also get 'array' cookies in two different ways:
print(Cookie::get('array[one]'));
print(
Cookie::get(array('array' => 'one')));

// Or you can grab the whole array at once:
print_r(Cookie::get('array'));

// Deleting cookies is done in the same way:
Cookie::del('array[one]');
Cookie::del(array('array' => 'two'));

// Delete the entire array:
Cookie::del('array');

// Print contents of $_COOKIE (refresh for this)
print '<pre>';
print_r(Cookie::contents());
print
'<pre>';
?>
mm at turkmenweb dot com
30.04.2009 18:11
Be aware of "Last-Modified" header when dealing with cookies.
If you are explicitly setting Last-Modified to a past time (a few hours, mins ago, or etc) then even though browser will update your cookie, it won't reflect on your page (if you say <?=$_COOKIE['yourcookie']?> , browser will still print old value). I have seen this in Firefox 3, and in IE8.

Here is the code:

<?php

if(isset($_GET['hide']) && $_GET['hide']=='y'){
setcookie("TmhabarMainNewsHide", 'y', time()+3600*24*1000,"/",".tmhabar.com",0);
}
elseif(isset(
$_GET['hide']) && $_GET['hide']=='n'){
setcookie("TmhabarMainNewsHide", 'n' ,time()+3600*24*1000,"/",".tmhabar.com",0);
}

$last_modified = filemtime('inc/somefile.html');
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified)." GMT");

echo
$_COOKIE['TmhabarMainNewsHide'];

?>

Last-Modified header above is being set to a time in the past (last modification time of a certain file). In the browser, after the '/?hide=y' call, output still remains 'n' -> as if cookie value hasn't changed. When you go to Firefox's "View Page Info", there cookie is set to 'y' (which is an expected behavior). Doesn't matter how many times I refreshed the page, or followed other inner links of the page, cookie value never changed. It only changes if you CTRL+F5 in the browser.

I guess this is an expected behavior of a browser, not to update the page if it's last-modified header is set to back in time. But on the other hand, dynamic values should change in page. So, just be aware :) Btw, everything worked perfectly once I have commented out the 'header("Last-Modified: "....' line in the code above.

Hope this helps someone. Peace.
Muhammed Mamedov
Steve
17.04.2009 10:04
Beware, the example below works fine on my testing server but didn't work on my providers server;

<?php
setcookie
("SessionID","a test cookie");
?>

Once the cookie is set my entire web site fails with messages
similar to.

 "An appropriate representation of the requested resource could not be found on this server."

I'd used similar code for years on another site, but where the value was numeric, I'd made a minor change to generate a random string for the session ID and then got this issue.

The solution is not to use the cookie name "SessionID", i.e.

<?php
setcookie
("SessionToken","a test cookie");
?>

works fine.
dan at reverb-marketing dot com
5.04.2009 20:49
Consider adding a version number to your cookie string.  That way if your site gets an upgrade and the contents of your cookie change then it won't create (as big of) a headache for old users.

<?php
$foo
=unserialize($_COOKIE['remember_me']);
if(
$foo['version']==1) {
 
// original cookie.  Ignore it?  Process it differently?
 
old_and_busted($foo['data']);
} else if(
$foo['version']==2) {
 
// new cookie, proceed as normal
 
new_hotness($foo['data']);
}
?>
maksymus007 at gmail dot com
13.02.2009 15:47
To resolve problem of time difference between time on server and on client, just set a cookie with maximum lifetime and as one of its fields set local server time, that will be compared while cookie is read.
paul at webtop-designs dot com
10.02.2009 20:14
If you are trying to send cookies and keep getting a message about headers already sent but you cannot find where, check your files...a single space after the closing ?> in php is classed as output and will cause this issue.

Zend Framework users will note the new technique and not closing your files at all...that is to combat this same problem.

Make sure that ?> are the very last 2 characters of your file.

//erlin
erikinc at bredband dot net
8.02.2009 22:03
When working with encryption and setcookie( ) the decryption might fail in an seemingly random manner, making the cookie seem corrupt. This is due to the fact that php url-encodes the data before sending it to the client, and may therefore effectively be changing the ciphertext. A decryption of a changed ciphertext will render the plaintext unreadable. Due to the fact that this error only occurs when the ciphertext acctually contains characters needing encoding can make it very hard to identify.

One way to solve this problem, is to implement the url-encoding in the script, by using urlencode( ) and urldecode( ).
Prior to setting the cookie, use urlencode( ):
<?php

$ciphertext
= $myEncryptionObject->encrypt( $plaintext );
$safeCiphertext = urlencode( $ciphertext );
setcookie( "myCookie", $safeCiphertext, 0, "", "", false, true);

?>

And then using urldecode( ) prior to decryption of the ciphertext:
<?php

$safeData
= $_COOKIE[ "myCookie" ];
$ciphertext = urldecode( $safeData );
$plaintext = $myEncryptionObject->decrypt( $ciphertext );

?>
Frank
9.12.2008 4:22
One note on storing information in an "array" in a cookie:

You CANNOT access that array as a normal array.

So for example if you store:

<?php
setcookie
("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");

$_COOKIE[cookie][one] returns nothing.
?>

You MUST use foreach to grab all the information listed in the example above.

Not sure if this is a bug in php or a "feature."

Hopefully, this can save others some time.
bogdan at moongate dot ro
11.09.2008 11:58
Beware of the Cookie Monster (http://preview.tinyurl.com/5964ho) -- always set $secure to true for cookies set within secure environments (i.e. when your code is being accessed via HTTPS).

Also be advised that PHP's session manager doesn't do that automatically -- by default starting a session within a secure environment sets a cookie which is then accessible via non-secure channels. For sessions started in secure environments use:

<?php INI_Set('session.cookie_secure',true); ?>

before starting the session.
Link dot random at gmail dot com
3.09.2008 23:49
Platform: Windows XP SP2, IIS5.2, Php5.2.5:

I've had my share of sessioning problems and all of them came from the fact that i'm using Php Designer 2007 as my php editor.. Cookies must be sent before any output from your script including <html> and <head> tags as well as any whitespaces, well this php editor was sending a sort of data before the headers that i want to send which cause to have the given error: "Cannot send session Cookie - headers already sent", even after using output buffers to fixe the problem of the time the cookies are sent i still had the same problem.
Solution? Don't use any editor..! notepad is all you need... Used notepad, and it worked like magic!
php at gigadepot dot com
27.07.2008 19:17
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;
    }
?>
jphansen at uga dot edu
22.04.2008 14:43
If you'd like to set a cookie for a prolonged time, here's an example for a cooking lasting 1 year, which passes seconds--60 seconds * 60 minutes * 24 hours * 365 days = 1 year--as the $expire argument.

<?php
setcookie
($name, $value, time()+(60*60*24*365));
?>
isooik at gmail-antispam dot com
26.02.2008 14:18
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
sebasg37 at gmail dot com
8.02.2008 16:10
As said, you can avoid the annoying "headers already sent in line..", using the ob_start() (function that serves as buffer) doing this:

<?php
ob_start
();

echo
"somtehing";
setcookie("cookie", "value"); /* if you didn't add the ob_start() function at this point the headers would have been already sent and the cookie have not been saved */

ob_end_flush();
?>
dave at shout411 dot com
4.02.2008 2:51
firefox will permit a short cookie length, eg +60
IE6 (all i tested as yet) will not create the cookie for +60
It will though accept +120 (two minutes)
d.
globexdesigns at gmail dot com
7.12.2007 1:45
Quotes are important when giving cookies parameters. If it looks like you can't delete your cookies, or cookies doesn't delete verify that both your cookies names are consistent.

<?php
setcookie
(mycookie, $test, time() + 3600);
setcookie("mycookie","",time() - 3600);
?>

The above is wrong. But the examples are right:

<?php
setcookie
("mycookie", $test, time() + 3600);
setcookie("mycookie","",time() - 3600);
?>

<?php
setcookie
(mycookie, $test, time() + 3600);
setcookie(mycookie,"",time() - 3600);
?>
Alexander Fleischer
29.11.2007 17:48
Using $httponly also prevents the browser to pass a cookie to the java class loader. If a session cookie is required to access java .class / .jar files, loading of the applet will fail. In this case, session.cookie_httponly may be switched off.
soeren dot spreng at gmail dot com
22.11.2007 11:35
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!
amalinovski at yahoo dot com
30.10.2007 9:29
Problem with setcookie() and UTF-8 recognizing by browser:
- If you want to use UTF-8 characters in your php file, some editors insert special bytes in the very beginning of the file. This prevents setcookie() from working, because these special bytes are sent to the browser BEFORE the header, and you get "Header already sent" error;
- If you delete these bytes (with a hex editor), setcookie() will work fine, but the browser will STOP recognizing UTF-8 encoding automatically! The user will need to set the encoding to UTF-8 manually to see your page correctly.
Here's how to get out of this:

Instead of:

<?php
setcookie
("aaa", "bbb");
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Write this:

<?php
header
("Content-Type: text/html; charset=utf-8");
setcookie("aaa", "bbb");
?><html>
<head>
...

(make sure you have no special bytes before "<?")
mikeh at view22 dot com
19.10.2007 20:56
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);
        }
}
?>
cwillard at fastmail dot fm
22.08.2007 16:55
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.
bluewaterbob
13.07.2007 8:51
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.)
john at codeproject dot com
17.06.2007 19:52
If you ever have to modify, add, or delete cookies (that you added with php) using Javascript, try using this piece of code i found here:
http://www.webtoolkit.info/javascript-cookies.html
Its rather simple and very useful.
jonathan dot bergeron at rve dot ulaval dot ca
24.05.2007 21:05
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
anonIMouS
10.04.2007 10:42
This code sets cookie with Max-Age.
See to:
http://www.zend.com/zend/week/week198.php#Heading3
http://www.faqs.org/rfcs/rfc2109.html
<?php
function set_cookie($Name, $Value = '', $MaxAge = 0, $Path = '', $Domain = '', $Secure = false, $HTTPOnly = false) {
 
header('Set-Cookie: ' . rawurlencode($Name) . '=' . rawurlencode($Value)
                        . (empty(
$MaxAge) ? '' : '; Max-Age=' . $MaxAge)
                        . (empty(
$Path)   ? '' : '; path=' . $Path)
                        . (empty(
$Domain) ? '' : '; domain=' . $Domain)
                        . (!
$Secure       ? '' : '; secure')
                        . (!
$HTTPOnly     ? '' : '; HttpOnly'), false);
}

# examples:
set_cookie("TestCookie", $value, 3600);  /* expire in 1 hour */
set_cookie("TestCookie", $value, 3600, "/~rasmus/", ".example.com", 1);
?>
Marcin Wiazowski
30.03.2007 22:08
'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'] : '');
?>
mike
26.03.2007 18:00
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.

21.03.2007 23:40
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.
gabe at fijiwebdesign dot com
25.02.2007 16:25
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, '/');
    }
}

?>

9.02.2007 2:13
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);

?>
brian dot powell at insetsolutions dot com
6.02.2007 3:35
Here is problem I ran into during a recent bout with IE7 and cookies.  IE will not delete a cookie value if the time is set to the past.  It will hold the value no matter how far in the past you set the "expire" value.  IE7 is the only browser I have had problems with - so here is the solution I came up with.

<?PHP

//check to see how to set the cookie
$Browsertype = $_SERVER['HTTP_USER_AGENT'];
$Parts = explode(" ",$Browsertype);
$MSIE = array_search("MSIE",$Parts);
               
if(
$MSIE)
{
setcookie("name", "", time()+20000);
}
else
{
setcookie("name", "", time()-20000, "/", ".domain.com" );
}

?>
ahmetantmen at msn dot com
19.01.2007 12:36
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!
stovenator at gmail dot com
13.01.2007 3:54
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.

5.01.2007 22:33
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.
felixcca at yahoo dot ca
31.12.2006 18:36
I found out recently that assigning FALSE to a cookie will destroy it.

I thought it might interest some of you.
kurtubba at gmail dot com
14.12.2006 2:12
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;
?>
paul nospam AT nospam sitepoint dot com
7.12.2006 5:59
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.
hansel at gretel dot com
6.11.2006 17:12
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).
adruff at gmail dot com
6.08.2006 7:14
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'.
gareth at gw126 dot com
5.06.2006 16:38
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
simon at ruderich dot com
1.08.2005 23:21
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.
terry at scribendi dot com
8.05.2005 16:07
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.
Carl V
8.04.2005 5:29
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).
Alchaemist
15.03.2005 0:36
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
apex at xepa dot nl
25.11.2003 3:59
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)]
Jörg Aldinger
1.10.2003 1:13
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).
dave at fubra dot com
9.09.2003 21:36
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
soreman at abv dot bg
12.04.2003 0:26
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.
mleer at sp dot nl
19.12.2002 23:50
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!
robert at ourwebhome dot com
6.12.2001 0:41
Internet Exploer 6 now requires sites that set cookies to have P3P policies.

From the Microsoft page:
"Internet Explorer 6 implements advanced cookie filtering that is based on the Platform for Privacy Preferences (P3P) specification. By default, Internet Explorer 6 blocks third-party cookies that do not have a compact policy (a condensed computer-readable privacy statement) or third-party cookies that have a compact policy which specifies that personally identifiable information is used without your implicit consent. First-party cookies that have a compact policy which specifies that personally identifiable information is used without implicit consent are downgraded (deleted when you close Internet Explorer). First-party cookies that do not have a compact policy are leashed (restricted so that they can only be read in the first-party context)."

See:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q260971&GSSNB=1

For more about P3P:
http://www.w3.org/P3P/



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)