Basically, a php session won't expire while a user is surfing on a website. But "while the user is surfing on the website" means that there are get and post requests. Nevertheless, i can't figure out if there has to be new requests, or if one active request is enough to maintain the session…
For instantce, i have a big file upload by post. It could then take hours. Will the session expire or not ?
The lifetime of a session depends on the ini setting session.gc-maxlifetime. Every access to the session (read and write) resets the timer. After the timeout, when the session garbage collector runs, the session values are destroyed.
The default value is 1440, which means 24 minutes. So if you have hits that access the session in any way at least every 24 minutes, the session values will stay.
If you need the session to stay alive longer than that, you can extend the timeout with ini_set (use before session_start()), for example:
ini_set('session.gc_maxlifetime', 24*60*60); // 24 hours
It shouldn't. Usually when I work with $_SESSION's, they last for a day or so. But it might on some servers. In that case you need to add cookies, too. With cookies you can exactly manipulate the time the person can be online for.
Related
How can I keep the user's session active, even if they accidentally closed their browser. Like in Facebook for example.
If you log in to their site and you close the tab or the browser, when you open a browser again and visits Facebook, they will automatically detect the active user and will not redirect you to the log in page.
How do I do that?
There's two relevant settings that control session's lifetime.
The first is session.cookie-lifetime. This is the lifetime of the cookie, which by default is 0, which means the cookie is destroyed when the browser is closed. You can set a longer lifetime by increasing this variable. It is relative to the server time, so you need to account for differences in the time in your clients' machine and your server's. Assuming they were the same, setting the option to i.e. 3600 would mean the session would expire in an hour. If you want to keep the session alive for a very long time, you increase this number.
However changing this value is not enough. There's also session.gc-maxlifetime, which is the time after which the session data is seen as garbage in the storage and is destroyed. This differs from session.cookie-lifetime because this option checks the last access time of the session data, so it is relative to the time the session data was last used (i.e. when the user was last active). Even if you set your session.cookie-lifetime to a high value, it'll not be enough because session.gc_maxlifetime is relatively low usually (1440 is the default, which is only 24 minutes).
While you can set these settings both to relatively high values and have it working, I would recommend against doing so, as this will leave a lot of unnecessary session data hanging around in your session storage, due to the GC not collecting actual dead session (which also increases the chance of someone hijacking a session in a system that is not properly secured). A better approach is making a remember me cookie. Basically you assign the user's ID and some authentication token that you store in the database for each user (this is to prevent someone spoofing the cookie) in the cookie, and give it a long lifetime. In your application's initialization code you'll check if the user is logged in. If he/she is not logged in, you'll check if the remember me cookie is set. If it is, you pull the user from the database based on the user ID in the cookie, and then validate the authentication token in the db is the same one as in the cookie. If they match, you simply create the session and log the user in automatically.
For anyone that come across this same issue, to keep the session cookie set for a long time is easy, on the login form, when you are creating the session for first time use this code, it will set the cookie time for a year (use your own time as its needed).
ini_set('session.cookie_lifetime', 60 * 60 * 24 * 365);
ini_set('session.gc-maxlifetime', 60 * 60 * 24 * 365);
session_start();
That should set the PHPSESSID cookie and your session will be safe... but is not the most secure way, so use it if you don't mind security issues
By default, PHP keeps a user's session open until their browser is closed. You can override that behaviour by changing the session.cookie-lifetime INI setting:
http://www.php.net/manual/en/session.configuration.php
However please see rekot post for a full answer
You should use cookies: http://php.net/manual/en/function.setcookie.php
Just store there some unique value that will help you identify the user.
Anyway, I strongly recommend you using some kind of framework, like CodeIgniter or Zend Framework, unless you're just learning how it works. It is easy to make critical mistakes in such a code and most frameworks are already well tested and safe to use.
I have read several articles on this topic but still don't fully understand the relationship between the client-side session cookie, the server-side session file, and the way PHP "randomly" chooses to remove or keep a session during garbage collection.
The behavior I am trying to ensure is:
a user logs in, and the session begins
if the user is inactive* for a period of 1 hour, the session is
destroyed
*this is critical for my site because the user may be spending an hour apparently "idle" on the same page, but in fact they are not idle. They may be composing a long written report, watching a video, etc.
What I'm using so far is:
session_start();
setcookie(session_name(),session_id(),time()+3600);
This code is executed on every page load.
I also have an AJAX request firing every minute via a setInterval, which loads a PHP script containing the above code on pages where the user is apparently "idle".
Will my approach ensure the behavior I require? Or am I missing something? Perhaps there is a cleaner way to ensure this behavior.
Many thanks in advance.
you could try something like this:
if (isset($_SESSION['LAST_ACTIVITY'])&&(time() - $_SESSION['LAST_ACTIVITY'] > 3600)) {
// this takes 60 minutes
session_unset();
session_destroy(); // destroy session data that is in storage
}
I ... still don't fully understand the relationship between the client-side session cookie, the server-side session file, and the way PHP "randomly" chooses to remove or keep a session during garbage collection.
The client-side cookie does not hold any info about the user. It's only a token, which is sent to the server with any other info with every new request. The expiration limit you are setting indicates how long the client-side cookie is valid.
Server-side session files and garbage collection is something else. In php.ini you may set session.gc_maxlifetime, defaulting to 1440, which indicates "the number of seconds after which data will be seen as 'garbage' and potentially cleaned up". And then there is session.gc_probability (defaulting to 1) and session.gc_divisor (defaulting to 100).
This means, that after 1440 seconds there is a 1/100 the garbage collector will start, cleaning the session, which now is considered garbage.
If you wish to remove the session after an hour with a 100% probability, set session.gc_probability to 0 and remove the old sessions manually. For this, you could save "last activity" in your database and cron a script, which removes sessions, which have "last activity" and time() difference larger, than 1 hour.
I'm wondering how long php sessions are stored in server memory.What if user logs in (sets session variables in server) and he keeps his browser open for a long time suppose 30 days and he reloads the page on the 31st day? Can browser access session variables(browser still has session cookie)?
Default php.ini sets the session expiration time to 30 minutes.
Check out these settings: session.gc_maxlifetime and session.cookie_lifetime
As long as the browser have the cookie stored, it doesn't matter if it is closed or is open.
If you want to store the session for lets say 30 days, you can add:
ini_set('session.gc_maxlifetime', 30*24*60*60);
ini_set('session.cookie_lifetime', 30*24*60*60);
Normally you would code as part of your session handling code a function for expiring sessions after some time has elapsed, so in that case it would't matter how long they left there browser open
I think this depends on what you have set in php.ini http://php.net/manual/en/function.session-set-cookie-params.php
I am a PHP novice and am trying to wrap my head around how sessions work. I had a general question about the behavior of sessions in php.
So I understand that every time session_start() is called the garbage collector may be invoked with a certain probability. So my first question is, lets say I only have 100 users of my website, and there are 2000 sessions stored in the session.save_path() folder on the web-server. If user A who is one of the 100 users logs in to the website and session_start() is invoked, are one of the previous sessions of user A destroyed or one of the 2000 sessions that belong to all the users destroyed?
My second question is, lets say user A is on the website for about 30 minutes and 'session.gc_maxlifetime' is set to 1440 seconds which is 24 minutes, after 24 minutes is there a chance the user A's session might be deleted by the garbage collector even though the user is still active on the website?
And if so is a new session with all the same information of the previously deleted session started every 24 minutes since this would have to be the case for prevention of loss of user data.
I apologize if these questions sound very rudimentary but I am quite confused about the session concept and would like the concept clarified.
Any help would be much appreciated.
PHP's session garbage collector runs with a probability defined by session.gc_probability divided by session.gc_divisor. By default this is 1/100, which means that above timeout value is checked with a probability of 1 in 100.
This means whenever a new session is started, there is a chance that garbage collector is triggered. Than all sessions that are older then the maxlifetime will be deleted
If someone is active on the site this session will never deleted. On every page refresh the actual session will be reset the lifetime of this session. Only not used sessions will be deleted. So if a user is just idling on the page and do nothing, this session could be deleted. And he have to start a new session.
I hope this helps you understand session
Garbage collection applies to ALL sessions, because PHP has no knowledge of session "ownership"; all session objects that are modified before time() - ini_get('session.gc_maxlifetime') will be removed.
Whenever a particular session object is accessed using session_start(), at the end of the request (implicit) or when session_write_close() is called (explicit), its modification time (should) get updated. This means that as long as a user keeps loading pages occasionally, the session is not destroyed.
Btw, I talk about session objects rather than files because the physical storage of sessions can be changed using session_set_save_handler().
How can I keep the user's session active, even if they accidentally closed their browser. Like in Facebook for example.
If you log in to their site and you close the tab or the browser, when you open a browser again and visits Facebook, they will automatically detect the active user and will not redirect you to the log in page.
How do I do that?
There's two relevant settings that control session's lifetime.
The first is session.cookie-lifetime. This is the lifetime of the cookie, which by default is 0, which means the cookie is destroyed when the browser is closed. You can set a longer lifetime by increasing this variable. It is relative to the server time, so you need to account for differences in the time in your clients' machine and your server's. Assuming they were the same, setting the option to i.e. 3600 would mean the session would expire in an hour. If you want to keep the session alive for a very long time, you increase this number.
However changing this value is not enough. There's also session.gc-maxlifetime, which is the time after which the session data is seen as garbage in the storage and is destroyed. This differs from session.cookie-lifetime because this option checks the last access time of the session data, so it is relative to the time the session data was last used (i.e. when the user was last active). Even if you set your session.cookie-lifetime to a high value, it'll not be enough because session.gc_maxlifetime is relatively low usually (1440 is the default, which is only 24 minutes).
While you can set these settings both to relatively high values and have it working, I would recommend against doing so, as this will leave a lot of unnecessary session data hanging around in your session storage, due to the GC not collecting actual dead session (which also increases the chance of someone hijacking a session in a system that is not properly secured). A better approach is making a remember me cookie. Basically you assign the user's ID and some authentication token that you store in the database for each user (this is to prevent someone spoofing the cookie) in the cookie, and give it a long lifetime. In your application's initialization code you'll check if the user is logged in. If he/she is not logged in, you'll check if the remember me cookie is set. If it is, you pull the user from the database based on the user ID in the cookie, and then validate the authentication token in the db is the same one as in the cookie. If they match, you simply create the session and log the user in automatically.
For anyone that come across this same issue, to keep the session cookie set for a long time is easy, on the login form, when you are creating the session for first time use this code, it will set the cookie time for a year (use your own time as its needed).
ini_set('session.cookie_lifetime', 60 * 60 * 24 * 365);
ini_set('session.gc-maxlifetime', 60 * 60 * 24 * 365);
session_start();
That should set the PHPSESSID cookie and your session will be safe... but is not the most secure way, so use it if you don't mind security issues
By default, PHP keeps a user's session open until their browser is closed. You can override that behaviour by changing the session.cookie-lifetime INI setting:
http://www.php.net/manual/en/session.configuration.php
However please see rekot post for a full answer
You should use cookies: http://php.net/manual/en/function.setcookie.php
Just store there some unique value that will help you identify the user.
Anyway, I strongly recommend you using some kind of framework, like CodeIgniter or Zend Framework, unless you're just learning how it works. It is easy to make critical mistakes in such a code and most frameworks are already well tested and safe to use.