You are using custom session.save_handler on your production server. You are probably not on your development machine.
Remember that Joomla really does block the session incorrectly - no. In essence, this means that you are a victim of a race condition.
If you look at the documentation for session_set_save_handler () , you will see that there are callbacks to open, close, read, write, destroy, and gc (garbage collection).
open should “initialize” the material, but most importantly, it must provide write locks for the source used for storage.
read regular reading is done, write .
close should release the write lock.
If the session persistence handler does not use locking, multiple concurrent requests with the same session identifier can overwrite each other!
A simple test that you should run on your server to find out if you have this problem:
<?php // initialize alternate session save handler here. //include_once "session-handler.php"; if (isset($_GET['subrequest'])) { $starttime = time(); $subrequest = intval($_GET['subrequest']); session_start(); // should wait until lock is released echo "<html><pre>"; echo "Request started on ". date("Ymd H:i:s", $starttime)."\n"; echo "Session locked for this request on ". date("Ymd H:i:s"). "\n"; echo "Executing subrequest ". $subrequest."\n"; $_SESSION["subrequest"][] = 'collected subrequest #'.$subrequest; echo "All subrequests collected:\n"; var_dump($_SESSION["subrequest"]); echo "\nWaiting 1 second\n"; sleep(1); echo "Releasing session lock on ". date("Ymd H:i:s"). "\n"; echo "</pre></html>"; exit(); } session_start(); $_SESSION['subrequest'] = array('master request'); ?> <html> <iframe src="?subrequest=1" width="90%" height="100"></iframe> <hr> <iframe src="?subrequest=2" width="90%" height="100"></iframe> <hr> <iframe src="?subrequest=3" width="90%" height="100"></iframe> </html>
This PHP file initializes the session and selects three frames on the screen, which almost immediately make three requests to the server again.
If the session is blocked, then each of the frames will be filled sequentially one after another in the following seconds. Also, in order of appearance, the control output of $_SESSION['subrequest'] should include ALL subqueries on the one that returned last.
If the session is NOT properly locked, all three frames will fill up almost instantly one second after loading the main page, and all will report only their own subquery along with the main request for debugging output.
If I use this implementation to store the file system, I got on the php.net documentation page (example No. 2) , the correct saving to the session fails!
<?php class FileSessionHandler { private $savePath; function open($savePath, $sessionName) { $this->savePath = $savePath; if (!is_dir($this->savePath)) { mkdir($this->savePath, 0777); } return true; } function close() { return true; } function read($id) { return (string)@file_get_contents("$this->savePath/sess_$id"); } function write($id, $data) { return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true; } function destroy($id) { $file = "$this->savePath/sess_$id"; if (file_exists($file)) { unlink($file); } return true; } function gc($maxlifetime) { foreach (glob("$this->savePath/sess_*") as $file) { if (filemtime($file) + $maxlifetime < time() && file_exists($file)) { unlink($file); } } return true; } } $handler = new FileSessionHandler(); session_set_save_handler( array($handler, 'open'), array($handler, 'close'), array($handler, 'read'), array($handler, 'write'), array($handler, 'destroy'), array($handler, 'gc') );
If I look at some classes of Joomla sessions, I would predict that storing in APC, database, and XCache will not be able to run this test because they use user-defined functions without the proper open or close implementation.
I don’t own Joomla, so you have to implement Joomla way to use sessions in this test script yourself.
One final note: if locking is not possible in one data set in the database (for example, you use MyISAM tables), then effectively you cannot use this table to store session data. Starting a lock on the table will stop ALL other USERS sessions.