PHP - Working of Cookies - php

I am facing a difficulty in understanding the usage of cookies in PHP,
Please consider the following code snippet
public function preExecute() {
setcookie("testCookie", "Hello123", time() + 31536000, "/", WebServer::getServerName());
echo "Before Value of cookine in decommission::".$_COOKIE["testCookie"];
setcookie("testCookie", "Hello456", time() + 31536000, "/", WebServer::getServerName());
echo "After Value of cookine in decommission::".$_COOKIE["testCookie"];
}
The output that i am expecting for this code
Before Value of cookine in decommission::Hello123
After Value of cookine in decommission::Hello456
But the output i am getting for the above code snippet is
Before Value of cookine in decommission::Hello456
After Value of cookine in decommission::Hello456
Will appreciate if someone explain me the working, i have gone through resources available in internet, but still i am not clear.
Thanks in advance.

$_COOKIE holds the cookies that have been received in the current request. It is not automatically updated when you call setcookie to set cookies in your response. The cookies you set via setcookie will only appear in $_COOKIE on the next request, when the cookies are sent back to the server.
So what you're seeing is that the second cookie overwrites the first, so only the later value is sent back to the server. I'll guess you have refreshed the page several times already, so you're seeing the cookie. If you clean your cookies and run this again, on the first try you won't see any output, because $_COOKIE is empty and stays empty for the whole request, no matter how often you call setcookie.

If you dont want to change this usage, use sessions. $_SESSION is a global array. You can reach from everywhere (inside class,function) and use instantly (no need to wait next request/page load).

Related

Why does this PHP setcookie() argument not set a cookie?

I have this PHP
setcookie('hello', '0', 0, '/389732/');
Why when I run it does it not set a cookie?
I printed the value of $_COOKIE['hello'] out immediately after and it puts out an error because it does not exist.
setcookie documentation spells this out:
Once the cookies have been set, they can be accessed on the next page load with the $_COOKIE ...
Edit: it might be tempting to manually insert that cookie into $_COOKIE yourself, but keep in mind that some frameworks helpfully parse $_COOKIE into other data structures on startup and will not see such hackish changes.
$_COOKIE gets populated when the script first runs. setcookie puts the cookie info in a queue that gets turned into a header when the page returns to the browser.
When the browser requests a new page, it sends the cookie information back to your server and the $_COOKIE variable will be populated.
Because the $_COOKIE is the content of the cookie when the php was called.

Php cookie not setting

Alright I'm totally baffled.
Here's my code:
if ($password == $correct_password[0] && !isset($_COOKIE['user'])) {
setcookie("user", $email, time() + 3600);
var_dump(isset($_COOKIE['user']));
echo "!";
}
So it's doing the var_dumps, meaning that the setcookie should called. But the line right after it (checking if it's set) says it's not set!
If anyone could point out the problem it'd be greatly appreciated. Thanks
$_COOKIE is populated/loaded when the script first starts up, and then is NOT updated by PHP again for the life of the script. Setting a cookie via setcookie will only show up in $_COOKIE on the NEXT execution of the script.
This applies to all of the superglobals, except $_SESSION. They're populated/initalized at script startup and then PHP does not ever touch them again. $_SESSION is populated when you call session_start() (or sessions are set to auto start), which may be done multiple times within a script's lifetime.
PHP is a server-side language.
That means that it can generate whatever it wants and will then pass it to the client.
And that's it.
There is no back and forward on a single request.
1º you instruct the page 'A' to set a cookie
2º client recieves page 'A' and sets the cookie
3º client asks for page 'B' (sending the cookie)
4º server can identify the cookie (only on page 'B')
Page here is used as simple way of understanding a server call.
You can request the same page twice for the purpose.
Still didn't find a solid valid answer, but after endless hours of testing it seems like something with the time. If I set the expiration date too close to the real time, maybe it doesn't register or something. It seemed to work when I set the time further, but I'm taking a break before heavy testing again.
Thanks
When you use setcookie() it will save its value the next time that the HTML is loaded. If you want to see the vardump with the value you just assigned you will need to use $_COOKIE['cookie_name'] = $value;

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.

PHP - funny behaviour of cookie variables and session variables

I wrote a little PHP script below to demonstrate my question. Run the code below like this: http://localhost/test.php?test=10, then run http://localhost/test.php?test=11, then http://localhost/test.php?test=12, etc. You will see that the number echo'ed to your screen is always 1 digit behind the url number?! Maybe because I cant a cookie and immediately read the same cookie?
//If query string has $test, store in session, and cookie for later.
if($_GET[test]){
$_SESSION['test'] = $_GET[test];
setcookie("test", $_GET[test], time()+60*60*24*30*12*10); //10 years
}
//If user comes back later, then get $test from cookie
if (isset($_COOKIE["test"])){
$_SESSION['test'] = $_COOKIE["test"];
}
echo "session test: " . $_SESSION['test'];
Later, I solved the problem with the following code, but solving it is not good enough, I want to know WHY this happened!
This solved it:
if($_GET[cid]){
setcookie("campaignid", $_GET[cid], time()+60*60*24*30*12*10); //10 years
$_SESSION['campaignid'] = $_GET[cid];
}elseif (isset($_COOKIE["campaignid"])){
$_SESSION['campaignid'] = $_COOKIE["campaignid"];
}
Maybe because I cant a cookie and immediately read the same cookie?
Exactly. The cookie you sent is available in $_COOKIE array only in the next request, because the $_COOKIE superglobal array is filled with the data, that comes in the client's request. And at first request it is nothing.
Technically you didn't start a session (session_start()) and you're using undefined constant test, however PHP is "intelligent" enough to figure out you mean a string "test".
What's exactly the question?
Maybe because I cant a cookie and immediately read the same cookie?
Yes, that's true. You've just proved it.
In your first snippet you are calling setcookie(). This sends a HTTP header to the browser. PHP does not update the $_COOKIES variable when you call setcookie(). The $_COOKIES variable is updated on the next script invocation, when the cookie is returned by the browser.

Cookie won't unset

OK, I'm stumped, and have been staring at this for hours.
I'm setting a cookie at /access/login.php with the following code:
setcookie('username', $username, time() + 604800, '/');
When I try to logout, which is located at /access/logout.php (and rewritten to /access/logout), the cookie won't seem to unset. I've tried the following:
setcookie('username', false, time()-3600, '/');
setcookie('username', '', time()-3600, '/');
setcookie('username', '', 1, '/');
I've also tried to directly hit /access/logout.php, but it's not working.
Nothing shows up in the php logs.
Any suggestions? I'm not sure if I'm missing something, or what's going on, but it's been hours of staring at this code and trying to debug.
How are you determining if it unset? Keep in mind that setcookie() won't remove it from the $_COOKIE superglobal of the current script, so if you call setcookie() to unset it and then immediatly print_r($_COOKIE);, it will still show up until you refresh the page.
Try pasting javascript:alert(document.cookie); in your browser to verify you don't have multiple cookies saved. Clear all cookies for the domain you're working on to make to sure you're starting fresh. Also ini_set(E_ALL); to make sure you're not missing any notices.
Seems to be a server issue. My last domain was pretty relaxed on PHP error handling while the new domain shows every error. I'm using both sites side by side and the old one removes the cookie as it should.
Is there perhaps a timezone issue here? Have you tried setting using something farther in the past, like time() - (3600*24)? PHP's documentation says that the internal implementation for deleting cookies uses a timestamp of one year in the past.
Also, you should be able to use just setcookie('username', false); without passing an expiration timestamp, since that argument is optional. Maybe including it is confusing PHP somehow?
How you use cookies data in your application?
If you read the cookies and check if username is not false or not '', then setting it to false or '' will be sufficient, since your application will ignore the cookies value.
You better put some security in cookies value, to prevent user change it's value. You can take a look of CodeIgniter session library, see how CI protect the cookies value using hash. Unauthorized value change will detected and the cookies will be deleted.
Also, CI do this to kill the cookies:
// Kill the cookie
setcookie(
$this->cookie_name,
addslashes(serialize(array())),
(time() - 31500000),
$this->cookie_path,
$this->cookie_domain,
0
);
You can delete cookies from javascript as well. Check here http://www.php.net/manual/en/function.setcookie.php#96599
A simple and convenient way, is to use this additional functions:
function getCookie($name) {
if (!isset($_COOKIE[$name])) return false;
if ($_COOKIE[$name]=='null') $_COOKIE[$name]=false;
return $_COOKIE[$name];
}
function removeCookie($name) {
unset($_COOKIE[$name]);
setcookie($name, "null");
}
removing a cookie is simple:
removeCookie('MyCookie');
....
echo getCookie('MyCookie');
I had a similar issue.
I found that, for whatever reason, echoing something out of logout.php made it actually delete the cookie:
echo '{}';
setcookie('username', '', time()-3600, '/');
I had the same issue; I log out (and I'm logged out), manually reload the index.php and then I'm logged in again. Then when I log out, I'm properly logged out.
The log out is a simple link (index.php?task=logout). The task removes the user from the session, and "deletes" (set value '' and set expiry in the past) the cookie, but index.php will read the user's auth token from the cookie just after this (or all) task (as with normal operations). Which will reload the user. After the page is loaded the browser will show no cookie for the auth token. So I suspect the cookie gets written after page finish loading.
My simple solution was to not read the cookie if the task was set to logout.
use sessions for authentication, don't use raw cookies
http://www.php.net/manual/en/book.session.php

Categories