I'm wondering how PHP detects that a specific session has timed out.
In detail: I'm using the default (file based) session handler, with a default session lifetime and so on. Everything in php.ini is on default.
If now a session is started, PHP does a check (depending non session.gc_divisor and session.gc_probability) if there are any timed out sessions. But from where does get PHP the last session access time from the sessions to check against?
The session file itself contains only the workload, e.g. x|i:1; for a $_SESSION['x'] = 1;, so there is no information about the last session access time.
I think that there are no in-memory information related to session start times as the sessions are still working after a full server restart.
So, where does PHP get the information from? Is it comparing the mtime/ctime of the session file?
PHP's default session handler stores the $_SESSION data in a file using serialize(), in the directory specified by session.save_path. Generally the filename looks something like $filename = 'sess_' . session_id().
Since it's just a file, PHP can use the file's mtime (time of last modification) to determine which session files are stale. Basically it'll grab all the session files whose mtime exceeds the session.gc_maxlifetime value and unlink() them. As you've said, the probability of the cleanup occuring is governed by the session.gc_* ini variables.
Now, if you create your own session handlers with session_set_save_handler(), this is all out the window, and you've now got control over how sessions are stored and cleaned up, but this does explain the default behavior.
Related
I want to manage my sessions in another folder than the defined by default.
So I have this in my code :
session_name('domain');
session_save_path($_SERVER['DOCUMENT_ROOT'] .'../sessions/');
ini_set('session.gc_maxlifetime',300);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
session_start();
The sessions are created by the serveur in the right folder and I connect correctly to the site but the sessions do not die passed the defined maxlifetime, here in the script 300, so 5 minutes.
The sessions are destroyed correctly by session_destroy() but it seems that the server do not destroy them by itself.
Did I miss something ?
I have read most part of the documentation but I can't find the cause.
Any idea ?
Well, in fact that's ok.
If the server do not delete old session files in the new session save folder, that's better cause that forced me to think and finally decide to control the sessions through the script itself.
I define in the script the lifetime of the sessions and if the lifetime is passed, I simply empty the session array and I regenerate the session_id(), deleting automatically the old session_id file (see in php doc, the true parameter in session_regenerate_id() function and I connect again automatically.
I will never have old lost session files in the folder cause the script make the optimum treatment.
:)
Solved
I have PHP 5.6 running on IIS 8.5. I used this test log:
echo '<p>'.sizeof($_SESSION).' - '.session_id().' - '.ini_get('session.cookie_domain').'</p>';
With it I see that $_SESSION has some elements, cookie_domain is properly set in php.ini as my domain, but session_id() has a different string on each page load. session_start() is being called on every page load.
Any idea on what I can do to make session persistent?
$sessionfile = ini_get('session.save_path') . '/' . 'sess_'.session_id(); shows where the session file is. I'm able to open it and data is there. Indeed it's something in the creation of each session, not in saving their files.
Is it possible that some IIS setting or some asp is reseting the session?
This problem occur most times if you don't have permissions to store the session in your IIS. I had the same problem before a long time. To correct the permissions or the session path solved my problem.
I have dedicated a server to maintain Memcached and store sessions, so that all my servers can work on the same session without difficulties.
But somehow I think I may have misunderstood the meaning of Memcached possibilities about PHP sessions.
I thought that I would be able to stand on Apache 1 a.domain.com and create a session e.g. $_SESSION['test'] = "This string is saved in the session" and then go to Apache 2 b.domain.com or c.domain.com and simply continue the session and type echo $_SESSION['test']; and it would output the string.
It doesn't, but i am sure that I was told that memcached would be a great tool if you have multiple webservers to share the same session.
What have I done wrong?
By the way. We seriously need a fully detailed tutorial or ebook to describe how to set up the server, using php, building clusters etc. based on Memcached.
In my php.ini file it says:
session.save_path = "192.168.100.228:11211"
Tutorials told me not to define a protocol, and the ip address has been given to the Apache 3 - memcached Server
Here is an image of phpinfo()
The domain in session.cookie_domain is not called domain but it is a .local.
It has been changed for this image.
EDIT:
Just for information. When I am using a simple Memcached based PHP command - everything works perfectly. But somehow when I am trying to save a session, the memcached server doesn't store the item.
This works:
<?php
$m = new Memcached();
$m->addServer('192.168.100.228', 11211);
$m->set('int', 99);
$m->set('string', 'a simple string');
$m->set('array', array(11, 12));
/* expire 'object' key in 5 minutes */
$m->set('object', new stdclass, time() + 300);
var_dump($m->get('int'));
var_dump($m->get('string'));
var_dump($m->get('array'));
var_dump($m->get('object'));
?>
This doesn't work
<?php
session_start();
$_SESSION['name'] = "This is a simple string.";
?>
EDIT 2: THE SOLUTION
I noticed that after deleting the cache history including cookies etc. the browser didn't finish the job. The problem continued due to the fact, that it hang on to the original individual session id, which made each subdomain separated from each other.
Everything defined here is correct, just make sure your browser resets its cookies when you ask it to. >.<
By default (session) cookies are domain specific, so set the cookie domain in your php.ini
session.cookie_domain = ".domain.com"
Also see here
Allow php sessions to carry over to subdomains
Make sure to restart your webserver and clear all of your browser cookies after making the change. Your browser could get confused if you have cookies with the same name but different subdomains.
Other things to check:
That the sessions work fine on each individual server.
Make sure the session handler is set properly by using phpinfo() if you are working with a large codebase especially inherited / 3rd party stuff there may be something overriding it.
If you are using 3rd party code - like phpbb for instance - check that the cookie settings are correct in there too.
(please note this answer tidied to remove brainstorming, kept all relevant info)
I have some issues concerning the timeout of a php session. I have set the following values during runtime of the application:
session.gc_maxlifetime = 3600
session.cookie_lifetime = 3600
session.save_path = myApplicationPath/tmp
session.use_cookies = 1
session.use_only_cookies = 1
However, my session keeps expiring in about 30 mins. Also, my tmp directory remains empty, so it appears no cookies are actually being set. echoing ini_get("session.save_path") does return the right path though.
Note:
If different scripts have different values of session.gc_maxlifetime but share the same place for storing the session data then the script with the minimum value will be cleaning the data. In this case, use this directive together with session.save_path.
PHP Manual
I'd say that PHP cannot find your save_path or does not have permission to write on that, so it stores session files (not cookies) in the default shared directory (so the site with shortest gc_maxlifetime will remove sessions from all other sites).
I have been at this for a day now, but nothing seems to be working.
What I want to do: change the expiry time of the session cookie PHPSESSID, when a particular checkbox is checked , how do I do this ?
I have tried:
ini_set()
session_set_cookie_params()
setcookie()
but nothing works . Can someone please please help me here ?
Thanks
To specify the session lifetime, server side, either apply the following command
ini_set('session.gc_maxlifetime', 30*60); // expires in 30 minutes
or set it in your php.ini file.
To set the session cookie lifetime, client side, either let it as it is (0, will die when the browser is closed), or
ini_set('session.cookie_lifetime', 30*60); // 30 minutes
or in the php.ini.
If you choose to use ini_set(), be sure to place the commands before session_start() is called.
Note that the ini_set function sets configuration option(s) during the script execution time only.
Regarding the checkbox and having a dynamic setting of the session lifetime, you could
use APC to store a setting shared by all PHP processes, that will last until the PHP server is down
write a value in a file somewhere that you load at the start of scripts (expensive) and set the value
(each script will have to ini_set() once before session_start())