How to create "namespace" in session valid until browser is closed? - php

For example, I'd like to create "namespace" in session that should be valid until browser is closed.
$_SESSION['other_data'] = array(...) - is valid until session is valid
$_SESSION['valid_until_browser_is_closed'] = array(...) - is valid until browser is closed.
The only "solution" I see is to create additional cookie that will exprire as browser is closed. And when accessing $_SESSION['valid_until_browser_is_closed'] we should check existense of this cookie first. Of course we should wrap working with sessions to some kind of class.
Thank you

Sessions will automatically expires after 24 minutes of inactivity from the client side. Also the cookie set into the client browser will be deleted as the browser is closed.
To be sure about the cookie being deleted you should try this:
session_set_cookie_params(0); // lifetime
And you should notice that you should call this function before starting the session as documented in the manual:
session_set_cookie_params(0);
session_start();
With that functions you are editing the session.cookie_lifetime parameter in the php.ini file which is (quoted from the documentation):
session.cookie_lifetime specifies the
lifetime of the cookie in seconds
which is sent to the browser. The
value 0 means "until the browser is
closed." Defaults to 0.
As for the namespace you could use (as already posted by Jon Skarpeteig) a bidimensional array:
$_SESSION['namespace']['var'] = 'value';
References:
session_set_cookie_params()
session.cookie_lifetime

A way of doing namespaces in the session is to use a two dimensional array like:
$_SESSION['namespace']['foo'] = 'bar';
Then you can invalidate the namespace by: unset($_SESSION['namespace']

Related

Does $_SESSION[]; create a session

I don't know if $_SESSION[]; creates a new session I think it does but I don't know;
If it does, should I put session_set_cookie_params(0); right before my session variable? like this
session_set_cookie_params(0);
$_SESSION['name'];
Thanks
session_start(); creates a session. $_SESSION just a global dictionary to store necessary values.
http://php.net/manual/en/function.session-start.php
session_set_cookie_params(0); gives cookies 0 seconds lifetime. It's simply cookies timeout definition. But there are more optional parameters.
http://php.net/manual/en/function.session-set-cookie-params.php
You need to put this at the start
session_start();
$_SESSION['name'] = 'Bob';
See http://php.net/manual/en/function.session-start.php
session_start(); starts / creates session
$_SESSION["sessionname"]=$value; assigns a value
echo $_SESSION["sessionname"]; - returns the value of the session
session_destroy(); -session destroy ends a session and revoves values
session_set_cookie_params(); - allows you to set other parameters for the session such as lifetime
either cookies or sessions can be used to make data available globally but session is more secure as it is stored server side while cookie is stored client side and can accessed by user. Even session uses a cookie but it only contains an id not the actual value which is stored on the server so session_set_cookie_params() is optional depending on if you want to change other parameters

session_get_cookie_params() doesn't work

I have a code snippet in application whose domain is http://localhost/xyz/
I am creating a cookie using a snippet
$cookie_name = "AMCV_98DC73AE52E13F1E0A490D4C#!#$%&~|AdobeOrg";
$cookie_value = "kuchbhi";
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/"); // 86400 = 1 day
right after this I am trying to execute session_get_cookie_params()to get the domain details of the cookie created above using below code snippet
$cookieInfo = session_get_cookie_params();
echo $cookieInfo['domain'];
But still I do not get any domain name, even on printing the array of $cookieInfo, I get empty array.
Please suggest how exactly does the function session_get_cookie_params() works..
Function session_get_cookie_params() is based on a bunch of php.ini file values:
session.cookie_lifetime
session.cookie_path
session.cookie_domain
session.cookie_secure
session.cookie_httponly
You can set values in your php.ini file, or you can override those values at the start of your script with:
ini_set('session.cookie_domain', 'www.example.com');
As the name suggests and the manual explicits, this function gathers info about session cookies:
session_get_cookie_params — Get the session cookie
Gets the session cookie parameters.
[...]
Returns an array with the current session cookie information
In other works, it's a fancy wrapper to read some PHP settings in one line, rather than issuing five calls to ini_get().
I suspect you are confusing cookies and sessions and possibly think they're synonyms. They aren't: cookies are a client side storage and sessions are a server-side storage. PHP happens to allow (and encourage) the use of cookies in order to transmit the session ID that tells the server-side storage who you are, but that's all. Think of the session cookie as the magnetic card that opens your office: that doesn't make your MasterCard has anything to do with doors.
If your question is "how do I get back my cookie parameters" the answer is that you can't. Open your browser's developer tools and you'll see that the browser never sends that information:

What is the best way to make "remember me" under php when using native sessions?

Previously i was creating additional cookie "rememberme" with unique hash, that was stored in the database, mapped to the user id.
If user had such cookie - website tried to find it's value in database, and if it was found session was setting up.
Later, developing new project i thought that it is maybe not very secure to generate this unique hash by myself, and keeping two cookies (native "PHPSESSID" + my "rememberme") for one operation (user identification) is overkill.
Maybe there is a way to setup not global session lifetime, but to setup it individually for different user sessions... or maybe it is better to keep user sessions in the database, mapped to the userid?
UPDATE 1
I thought if it is so hard to make "remember me" button, we can go another way - to make "Not my computer button". Idea is to set default cookie_lifetime for a week in php.ini (for example), and if user checkes this checkbox - we will set cookie_lifetime into zero using session_set_cookie_params function.
So, 1st question is - will session_set_cookie_params affect other users cookies (in documentation it is said, that session_set_cookie_params options will have effect until php process will be executing)
2d question is that if session_set_cookie_params is not affecting global settings, will session regeneration affect users, that don't want to keep a long-life cookie?
UPDATE 2: [Question 1 answer]
Just tested session_set_cookie_params function.
I wrote a script, that sets session cookie lifetime into zero using session_set_cookie_params and then executing for 30 seconds:
if ($_GET['test']) {
session_set_cookie_params (0);
while (true) {
sleep(1);
}
}
session_start();
So, in first browser i just started this script with ?test=1 parameter, just after that (while this script was executing) i started this script without parameters in the second browser. The answer is no - second browser's cookie was not affected. It had lifetime, that was specified in php.ini
UPDATE 3: [Question 2 answer]
Then, i've tried to check if regeneration affects session cookie lifetime, that was set by session_set_cookie_params.
Yes, it affects. If i set session cookie with customized lifetime, that was set by session_set_cookie_params, and then call session_regenerate_id(), cookie will have lifetime, set in php.ini
But, if we set session_set_cookie_params (0) before calling session_regenerate_id(), our cookie will have correct lifetime.
So, that's it! That was easy! 8)
Thank you, ladies and gentlemen!
If you want to do this only using sessions you can do the following if the user wants to be remembered:
if((isset($_POST['remember_me']) && $_POST['remember_me']) || ($_COOKIE['remember_me']) && $_COOKIE['remember_me'])) {
// store these cookies in an other directory to make sure they don't
// get deleted by the garbage collector when starting a "non-remeber-me"-session
$remember_me_dir = ini_get('session.save_path') . DS . "remember_me_sessions";
// create the directory if it doesn't exist
if (!is_dir($remember_me_dir)) {
mkdir($remember_me_dir);
}
// set the php.ini-directive (temporarily)
ini_set('session.save_path', $remember_me_dir);
// define lifetime of the cookie on client side
$expire_cookie = 60 * 60 * 24 * 30; // in seconds
session_set_cookie_params($expire_cookie);
// lifetime of the cookie on server side
// session file gets deleted after this timespan
// add a few seconds to make sure the browser deletes
// the cookie first.
$garbage_in = $expire_cookie + 600; // in seconds
// set the php-ini directive for the garbage collector of the session files.
ini_set('session.gc_maxlifetime', $garbage_in);
// send an additional cookie to keep track of the users
// which checked the 'remember_me' checkbox
setcookie('remember_me', 1, time() + $expire_cookie);
}
// now we are ready to start the session
// For all the users which didn't choose to check the 'remember_me' box
// the default settings in php.ini are used.
session_start();
Here you can read more about the session related php.ini-directives
As it was so hard to make "remember me" checkbox functionality, i came to another way, using only one cookie.
PREPARATION
1) I've prepared a form with three inputs:
"login" input [type=text]: user's login
"password" input [type=password]: user's password
"not my computer" input [type=checkbox]: that will tell us to use session cookie with lifetime = 0 (cookie must be deleted when browser will be closed)
2) I've set session.cookie_lifetime = 100500 to keep long-life cookies by default.
COOKIE SETUP
So, after user submits the form, we check - if he has selected to use short sessions - we call session_set_cookie_params(0) before setting session cookie to him (before actually using session_start()).
COOKIE REGENERATION
Then, when we need to regenerate session cookie, we can also do this easily with session_regenerate_id() function.
But we need to remember, that this function will re-set session cookie lifetime from php.ini by default.
So, we need also to call session_set_cookie_params() before regenerating a cookie.
BTW, You can store custom session cookie lifetime in $_SESSION.
It will look like this:
// Form handling, session setup
if ($_POST['not-my-computer']) {
session_set_cookie_params(0);
session_start();
$_SESSION['expires'] = 0;
}
// Session regeneration
if (isset($_SESSION['expires'])) {
session_set_cookie_params(0);
session_regenerate_id();
}
Details for this answer (and more deep explanations) you can find in the question text (while i was testing, i added answers/tests results there)

How do you update a cookie in 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,"/");

PHP: How to make session cookies kept until browser cloeses?

I'd like to set the PHP session lifetime as long as possible util the browser is closed. Is it possible to implement this just by settings something in PHP script? Or do I have to change anything in PHP.ini configuration file?
PHP's default session setting is to make the session cookies... session cookies. They'll last for the lifetime of the browser and get deleted when it's closed/quit/exited. The relevant .ini setting is session.cookie_lifetime
I just went through this myself recently.
Here is the website I used:
http://www.captain.at/howto-php-sessions.php
Pay attention to the "session.php" section at the bottom.
before any output;
<?
session_set_cookie_params(0);
session_start();
/* Set to 0 if you want the session
cookie to be set until the user closes
the browser. Use time() + seconds
otherwise. */
?>

Categories