How do you update a cookie in PHP? - php

If I call setcookie() two times with the same cookie name, I get two cookies created.
How do you update an existing cookie?

You can update a cookie value using setcookie() function, but you should add '/' in the 4th argument which is the 'path' argument, to prevent creating another cookie with the same name.
i.e. setcookie('cookie_name', 'cookie_value', time()+3600, '/');
A suggested expiration time for the 3rd argument:
$exp_time = time()+3600; /* expire in 1 hour */
$exp_time = time()+86400; /* expire in 1 day */

You can't update a cookie per se, you can however overwrite it.
Otherwise, this is what you are looking for: http://php.net/manual/en/function.setcookie.php
It works. Be sure to read "Common Pitfalls" from that page.
You can use the super global $_COOKIE['cookie_name'] as well to read cookies.

Make sure there is no echo before setcookie call. setcookie communicates with browser through header, and if you called echo earlier, header+body is sent already and server cannot send setcookie to browser via header anymore. That is why you might see it is not working.
There should be a line like below in php server log file reporting warning in this case:
DEFAULT: PHP Warning: Cannot modify header information - headers already sent by (output started at /path/to/your/script.php:YY) in /path/to/your/script.php on line XX

So while PHP will send two Set-Cookie: headers if instructed so, only the last one should persist in browsers.
The Netscape cookie spec http://curl.haxx.se/rfc/cookie_spec.html says:
Instances of the same path and name will overwrite each other, with the latest instance taking precedence. Instances of the same path but different names will add additional mappings.
However, it might be advisable to avoid such edge conditions. Restructure your application so it doesn't need to override the already sent cookie.

call COOKIE and delete username value
SETCOOKIE("username",'',0,"/");

Related

Unable to access cookie after page redirect

I am setting a cookie containing a vlue in this format and redirecting to another page via the PHP header function. Here's the code,
setcookie("myCookie", $cookieValue, time() + $cookieLife, "/"); // cookieLife is expiration time in sec
header("Location: $baseURL/index.php"); // $baseURL is "http://localhost/mysite"
The cookie is getting set within the browser. However, I am unable to access the cookie value in the redirected page, i.e., "index.php". I am trying to access the cookie value with a simple echo like this,
echo $_COOKIE['myCookie'];
However instead of the cookie value, I get the following notice,
Notice: Undefined index: myCookie in /path/to/my/site/index.php on line 1
I have set the cookie path to "/" after looking at other solutions but am still unable to solve this.
Any help much appreciated.
EDIT :
I am testing this on XAMPP server, and the "mysite" here is actually an alias for another location on my hard drive. Could this be causing this issue?
I assume your cookie gets removed or dissapears once you've left the previous page.
Check if time() + $cookieLife is the desired time you want the cookie to live. The PHP setcookie function tells me that your $cookieLife is the time in seconds that you want your cookie to live, so make sure that it's the value you want it to be.
Use an extension to check your current cookies (and alter them if you need to). This way you can check and make sure if the cookie is living as long as you want it to (you already mentioned seeing the cookie being set, but I will include this just in case + for future visitors).
FireFox Extension: Web Developer
Chrome Extension: Cookies

Prevent php session_start() to send a cookie

I would like to know if there is a way to prevent PHP from sending a cookie when calling session_start().
My use case is for a site optimisation:
(1a) I first open a session/send headers.
(1b) Then generate and output some text content.
(1c) To enhance session read/write I call "session_write_close" as soon as I don't need to write in the session anymore.
(2) Finally I have a post-page rendering process (for stats) that requires a write access to the session. The session is closed, I cannot call session_start() again since it sends a cookie and it's to late for that. This is a computation-heavy process, so I have to do it after the page is sent to the client.
The client already received a session-cookie. So I don't need session_start() to send a new (and redundant) one.
Does someone know a way to intercept the cookie or something similar ? Of course I want to avoid the "Cannot send session cookie - headers already sent". This error is invisible for the user because the page is already renderered but it looks ugly in the logs.
My question seems to be a redundant one, but it is not. I know how headers and content work (send headers first, content after). It's just that PHP does not let me do what I want.
I would like to know if there is a way to prevent PHP from sending a cookie when calling session_start().
Yes there is, by telling PHP to not use cookies for sessions. The PHP setting is session.use_cookies:
ini_set('session.use_cookies', 0); # disable session cookies
session_start();
By default cookies are enabled because they are considered more safe then using URL parameters (see Sessions and security­Docs).
(2) Finally I have a post-page rendering process (for stats) that requires a write access to the session. The session is closed, I cannot call session_start() again since it sends a cookie and it's to late for that. This is a computation-heavy process, so I have to do it after the page is sent to the client.
It's probably possible to tell PHP that the cookie is already set by adding it into the $_COOKIE superglobal array­Docs. I never experimented with it, but in case you use session_start() and PHP sees that the session cookie has been already set (by the browser, not PHP, $_COOKIE represent the browser cookies), it won't send the headers (again) to set the cookie (which as I understand you is what you want).
Edit: Some test script to play around with:
<?php
header('Content-Type: text/plain;');
echo "Incomming Cookies:\n";
print_r($_COOKIE);
// to simulate that this is a new session, the session cookie is removed
// which makes PHP think it is a new session when invoking session_start()
// unset($_COOKIE['PHPSESSID']);
// run the first session
session_start(); // creates the session cookie (as we don't have one yet)
printf("Session %s has been started: %s\n", session_name(), session_id());
var_dump($_SESSION);
$_SESSION['variable'] = isset($_SESSION['variable']) ? $_SESSION['variable']++ : 0;
session_commit();
printf("Session has been closed, remaining id is: %s\n", session_id());
// visual confirmation that session cookie has been created
echo "Outgoing Cookies:\n";
print_r(headers_list());
// run the second session
ini_set('session.use_cookies', 0); # disable session cookies
session_start();
printf("Second session %s has been started: %s\n", session_name(), session_id());
var_dump($_SESSION);
$_SESSION['2nd-variable'] = isset($_SESSION['2nd-variable']) ? $_SESSION['2nd-variable']++ : 0;
session_commit();
You need to call it with a web-browser (and PHP sessions must be configured to work).
I thought I should mention another great way to prevent the cookie (and the cache limiter) headers from being sent when calling session_start.
The session_start call takes an options array where you can set any of the session. prefix variables, and you can disable these things for just that call.
session_start(array(
'use_cookies' => '0',
'cache_limiter' => ''
));
Note that use_cookies keeps the cookie from being sent, and setting the cache limiter to an empty string keeps it from updating the cache headers (not the best documented feature).
Here are two notices that this will fix (this is helpful when you need to work through multiple sessions).
Warning: session_start(): Cannot send session cookie - headers already sent
and
Warning: session_start(): Cannot send session cache limiter - headers already sent
You can use ob_start() function to buffer the headers/content, you may clear the buffer contents using ob_clean()

How to set a cookie for a domain in PHP?

I want to set a cookie via PHP. The scenario is like this:
Domain is: example.com
There is one web page on sub-domain (my.example.com). My code is:
$value="I am looged in";
setcookie("TestCookie", $value,'','',".example.com");
echo "hello".$_COOKIE["TestCookie"];
but the result is only "hello" - the cookie is not getting set.
First two corrections to the actual call of setcookie: Parameter 3 (expired) should be an integer value (the default value is 0); parameter four should be set to '/' to make the cookie valid for all subdirectories; the setcookie call should therefore look like this:
setcookie("TestCookie", $value, 0, '/', ".example.com");
Then it should actually work the second time the script is called. To understand why it won't work the first time already, we have to dig in a little into how cookies work; basically, Cookies are data sent from the server to the client, where the server says "send me this data the next time you send me a request". That's basically what setcookie is for: When the request is done and the client has received and processed the page, the cookie as specified will have been created at the client; $_COOKIE, on the other hand, holds all values which are in cookies already, and which have been transmitted by the client along with the request - meaning that the first time the script is called, $_SESSION will actually still be empty, since the cookies will only be created once the client has received the scripts output.

Unable to set cookie if it does not already exist in PHP

I am trying to set a cookie for a site if it does not exist. It is not working.
if(isset($_COOKIE['about'])){
$_COOKIE['about'] += 1;
}
if(!isset($_COOKIE['about'])){
setcookie("about", 1, time()+3600);
}
I have also tried
if(empty($_COOKIE['about'])){
setcookie("about", 1, time()+3600);
}
The $_COOKIE superglobal is only available for you to read values from. Writing to it does not update the cookie, since that requires a new Cookie header to be sent to the browser. You would probably be better served by sessions backed by cookies, since PHP allows you to modify the session without explicitly saving/setting the cookie.
You can only read stuff from the $_COOKIE superglobal, try setting it normally:
setcookie("about",$_COOKIE['about']+1,time()+3600);
So all together:
if(isset($_COOKIE['about'])){
$_COOKIE['about'] += 1;
}else{
setcookie("about", 1, time()+3600);
}
Note the else, you've checked before if the cookie isset, so there is no need to check again as either it is or it isn't.
Make sure you have not sent any information to the user yet as the setcookie call is just an alias to header() (but with a specific schema to follow). You may have error output disabled and are missing the message, so it appears to work but is failing in the background.
setcookie should be one of the first calls on your page, up there with starting a session and setting a header.

how to use variable in setcookie()?

I want to pass a variable set by the user to the setcookie function.
I would like to let user change the color of some parts of website. so far the information about color is sent to server with $_SESSION['colorcode'] and I would like to add it to setcookie as well so when the user logs in to the site next time, his/her color is there.
I've got this code:
setcookie(
'colorcode',
$_SESSION['colorcode'],
time() + 60 * 60 * 24 * 30,
'',
'',
false,
true
);
I would like to save the value of variable in cookie, but it works just for the session.
what is wrong? how to do it so the color is there when the user logs in? I'm looking for another way than storing it in database or file.
Did you read back the value from the cookie at the beginning of the next session? Setting the cookie looks good but I think the last parameters could be omitted.
setcookie("colorcode", $_SESSION['colorcode'], time()+3600*24*30, '/');
Perhaps even the path ('/') is optional. But this only sets the cookie. You have to read the data back in, when the user returns to your site the next time.
if ( !isset($_SESSION['colorcode']) and isset($_COOKIE['colorcode']) ) {
if ( preg_match('/^#?[0-9a-fA-F]{6}$/', $_COOKIE['colorcode']) ) {
$_SESSION['colorcode'] = $_COOKIE['colorcode'];
} else {
// bad value... delete cookie if you like
}
}
When there is no colorcode in the session but the cookie-value exists, then the data is validated and if it's a valid 6 digit hex color code, then the value is inserted into the session. The validation is nessessary because a cookie is data that comes from the user and therefore potentially malicious.
This should work just fine:
setcookie("colorcode",$_SESSION['colorcode'],time()+60*60*24*30);
Just make shure you output it in the headers, I guess:
setcookie() defines a cookie to be
sent along with the rest of the HTTP
headers. Like other headers, cookies
must be sent before any output from
your script (this is a protocol
restriction). This requires that you
place calls to this function prior to
any output, including and
tags as well as any whitespace.
Do you get errors?
Try to check this:
setcookie('colorcode',$_SESSION['colorcode'],time()+60*60*24*30);
since cookie related functionalities (setcookie(), ...) work with HTTP headers, you should user them before any output is sent to client. but this does not mean these functions should appear at the beginning of your code. just make sure no output has been sent. even a single space character at beginning of your file outside of

Categories