Symfony:自定义会话保存处理程序最长执行时间

Rex*_*low 22 php session symfony

我正在使用Symfony的自定义会话处理程序.当我第一次设置会话但刷新页面时,它工作正常.页面将继续加载,max_execution_time在php.ini中定义的30秒后,将显示错误.为了设置自定义保存处理程序,我在棘轮数据库中创建了一个表会话.表中的结构和数据:

会话表的数据和结构

现在,页面顶部的脚本看起来像这样初始化自定义保存处理程序:

<?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');
Run Code Online (Sandbox Code Playgroud)

第153行的PHP脚本引发的错误:

错误

第153行是以下方法中的语句,它从数据库执行和读取会话值.

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
Run Code Online (Sandbox Code Playgroud)

框架的组件中是否存在某些问题,或者我遗漏了什么?我已经按照文档.我找不到任何新的或自己添加的东西.

加成

除了在Web应用程序中初始化会话之外,我还在我的server脚本中初始化symfony会话,因为为了将相同的会话对象附加到每个连接,它是必需的.需要注意的要点:

  1. 该应用程序适用于第一次尝试.
  2. 聊天服务器按预期工作.它永远不会抛出错误.
  3. 当我连接到websocket服务器的页面刷新时,它将保持加载状态30秒.然后发生错误.
  4. 其他浏览器也是如此.喜欢它会让连接建立,但是当我刷新........见上文:D

小智 6

你提到过:

我也在我的服务器脚本中初始化symfony会话

这也叫new NativeSessionStorage吗?

我认为正在发生的是你基本上创建了两个会话处理程序,但PHP只知道一个,因此只关闭数据库连接/提升其中一个数据库锁.让我看看我能否清楚解释一下.每次实例化NativeSessionStorage时,类都会使用php注册sessionHandler(在您的情况下为pdo会话处理程序)session_set_save_handler,您可以在此处查看NativeSessionStorage代码.

当PHP停止执行时,它会调用该PdoSessionHandler->close()方法.但是,因为你有两个实例,php只有一个注册为会话处理程序,它关闭一个而不是另一个.这使数据库锁定.根据您的描述,我认为这可能是您的问题.您应该能够通过显式调用Session->save()try在应用程序和服务器代码中显式执行此操作来轻松测试,以查看是否再次出现锁定错误.

希望这可以帮助!


Mar*_*hée 5

当websocket断开连接时,会话是否关闭?如果没有,它将保持对会话记录的锁定,并且不允许传入请求继续经过会话.初始页面加载有效,因为websocket在页面加载完成时选择会话.