I am using Symfony's Custom Session handler. It works fine when I set the session for the first time but when I refresh the page. The page will keep on loading and after 30 seconds which is max_execution_time
defined in php.ini, the errors are shown. To setup custom save handler, I created a table sessions in ratchet database. The structure and the data in the table:
Now the script, on the top of page looks like this to initialize custom save handler:
<?php
ini_set('session.auto_start', false);
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
require dirname(__DIR__) . '/vendor/autoload.php';
$pdo = new \PDO('mysql:host=localhost;dbname=ratchet', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$storage = new NativeSessionStorage(array(), new PdoSessionHandler($pdo)); // Here when PdoSessionHandler class is initialized again on refreshing it locks the page there
$session = new Session($storage);
$session->start();
$username = $session->get('username');
The errors thrown by PHP script for Line 153:
Line 153 is a statement in the following method which executes and reads a session value from database.
private function doRead($sessionId)
{
$this->sessionExpired = false;
if (self::LOCK_ADVISORY === $this->lockMode) {
$this->unlockStatements[] = $this->doAdvisoryLock($sessionId);
}
$selectSql = $this->getSelectSql();
$selectStmt = $this->pdo->prepare($selectSql);
$selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$selectStmt->execute(); // Line 153
Is something broken in the framework's component or am I missing something? I have followed the documentation. I can't find anything that is new or has been added by myself.
In addition to initializing session in the web app, I initialize symfony session in my server
script as well because it is required in order to attach the same session object to each connection. The points to be noted:
You mentioned that:
I initialize symfony session in my server script as well
Does this also call new NativeSessionStorage
?
What I think is happening is that you are creating essentially two session handlers but PHP only knows about one and thus only closes the database connection / lifts the database lock for one of them. Let me see if I can explain clearly. Every time you instantiate NativeSessionStorage the class registers the sessionHandler (the pdo session handler in your case) with php via session_set_save_handler
which you can see in the NativeSessionStorage code here.
When PHP stops execution it calls the PdoSessionHandler->close()
method. However since you have two instances and php only has one registered as the session handler, its closing one but not the other. Which keeps the database locked. Based on your description I think this may be your problem. You should be able to easily test this by explicitly calling Session->save()
try doing this explicitly in your app and server code to see if you don't get the locked error anymore.
Hope this helps!
Is the session closing when the websocket disconnects? If not, it is keeping the lock on the session record and not allowing the incoming request to continue past starting the session. The initial page load works because the websocket picks up the session when the page load is complete.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With