PHP - funny behaviour of cookie variables and session variables - php

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.

Related

PHP set PHPSESSID

I am trying to set the PHPSESSID from a value I received from a CURL POST. However, it is not setting when I assign it to the session_id(). The first echo statement is the correct PHPSESSID from the curl post. However, the second echo returns empty. Any thoughts?
PHP
//set current session id
session_id($sessID[1]);
echo "current SessID: " . session_id();
//start session
session_start();
echo "PHPSESSID: " . $_COOKIE['PHPSESSID'];
PHP's superglobals are populated with data when the script starts up, and then they are NOT touched again by PHP for the life of the script. Your new session ID will only show up on the NEXT request, after the new session cookie's had a chance to round-trip through the client's browser.
You cannot echo anything before doing session_start(). Per the docs:
Note: To use cookie-based sessions, session_start() must be called
before outputing anything to the browser.
http://us3.php.net//manual/en/function.session-start.php
The way you have it now is messing up the cookie. And you don't want to be messing up the cookies. :) The end result is the client never recognizes a session id cookie.

Using session variable to use info on different pages

i'm having a bit of a problem. I'm trying to set up a simple webpage with only three .php pages. I want a session variable $_SESSION['userID'] to be set when a user is logged in and I want the index page to show extra info if someone is logged in.
On index.php I want to show some info, if a user is logged in I want to show some extra info.
login.php - simple log in form.
login_exe.php - takes care of database connection and verification.
So this was my idea:
On index.php, check if session is started, if not: start.
<?php
if (!isset($_SESSION)) {
session_start();
echo "session started";
}
later on, check if $_SESSION['userID'] contains a value, if so: print a string
if($_SESSION['userID'] != null){
echo "User logged in";
}
On login_exe.php i've almost the same code:
<?php
if (!isset($_SESSION)) {
session_start();
echo "session started";
}
in verification function:
$_SESSION['userID'] = $data['userID'];
header("Location: index.php");
The problem is that a new session is started on every page. How can I fix this and only start the session once? Thanks in advance
You should just put session_start() on top of documents that using sessions. Say, if you have 5 .php files that using sessions, then put 5 times the session_start() on top of them.
This is because session_start() sends headers and headers must be sent before any output (for example, any echo or whitespace).
Then, you should use something like isset($_SESSION["foo"]) and not just the entire $_SESSION array, where foo is something you set previously.
If you dont want sessions at all or need to reset the entire array, just call session_destroy() which effectively destroy the current session. Use unset($_SESSION["foo"]) when you want to get rid of a key.
Finally, you might get weird cases where you cannot read session key you write at. In these cases check what is the path of sessions and if they're writeable, or change their path:
$path = session_save_path(); // what is the path
is_writable($path); // can i write to it?
session_save_path("my/new/path"); // change the darn path;
// put -even- before session_start()!
:)
glad i help
I think the PHP manuals are really good compared to ...ahm, so just read about session_start(). It says:
session_start() creates a session or resumes the current one (...)
so all you need is session_start() very early in your code. This must be executed on every request (maybe as include).
Your code checking the userId looks fine, one important hint here: you should know exactly what isset(), empty() and the like mean in PHP, so always have the comparision of comparison at hand.
You should not ask new answers (edit: questions) in comments. Be as systematic here as you are in coding.
How to end a session:
This gives room for discussion, because there is the session cookie, which is client side, and the session data, which is server side.
I recommend:
$_SESSION = null;
Reason: this will clear all login and other associated data immediately. It leaves the cookie intact, which is normally of no concern, since all associated data is gone.

PHP - Working of Cookies

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).

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;

Properly using session_set_cookie_params

I am trying to implement a login system with a 'remember me' feature . This is my my login page: http://pastebin.com/q6iK0Mgy . In this I am trying to extend the session cookie(PHPSESSIONID) expiration using session_set_cookie_params() . But its not working.
Relevant portion from the code: In this the inner if() loop is being executed , but session_set_cookie_params('3600') is having no effect. I am calling session_name() , as it is supposed to be a requirement for session_set_cookie_params() (according to one of the comments on php manual)
if ( isset($_POST["submit"]) )
{
session_name() ;
echo "calling before checked " ;
if ( $_POST["remember"] == "on")
{
// extend expiration date of cookie
session_set_cookie_params('3600');
echo "<br/>calling after sessions_set_cookie_params" ;
}
}
require_once("includes/session.php"); //session start ?>
I hope I was able to explain what I want to do. Basically what I a trying to do is extend the session_cookie's expiration. is my way of doing completely wrong? is there another way to achieve the same ?
thanks
Never too old for an answer right?
So, PHP is dumb. As in, it doesn't do what you think would make sense.
session_set_cookie_param will not do anything until the exact moment that you call session_start. So if you set cookie params after calling session start, too late. If you set the cookie params but then don't call session_start, nothing happens.
session_start is also a funny beast. It only reads cookie data the first time it is called -well that is unless.... you force it to write, or there is no cookie to begin with. So if there is no cookie, it writes the cookie data and the client saves your session. yay! But when the cookie exists already, how to we force it to write, and therefore update our new expiry date??
So, we have this odd effect of ignoring all of your session_set_cookie_param calls if a cookie already exists on the client. Even better, if you explicitly call setcookie(session_name(),blah blah blah), php will STILL not emit the cookie.
So, let's force php to emit a cookie.
option 1
This works by calling session_id with the only value that won't clobber your existing session. Documentation at http://php.net/session_id states that
Note: When using session cookies, specifying an id for session_id() will always send a new cookie when session_start() is called, regardless if the current session id is identical to the one being set.
session_id($_COOKIE[session_name()]);
So anyways it's 6 in the morning and I haven't slept yet and you probably figured this out months if not years ago, but what the hell, maybe i'll save someone else the 2 or 3 hours of my life i'll never get back. ha ha.
From the documentation:
You need to call
session_set_cookie_params() for every
request and before session_start() is
called.
Also check http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime

Categories