我有一个带有DbTableGateway的Zend \ Session Manager来处理会话。我的代码在another SO answer。但是每当会话到期时,我都会收到错误Fatal error: Maximum function nesting level of '100' reached, aborting! in [path]\vendor\zendframework\zend-db\src\Sql\AbstractExpression.php on line 40
我发现如何将xdebug嵌套级别更改为200,但我也达到了200限制。
所以我在DbTableGateway-> read()和DbTableGateway-> destroy()之间有一个无限循环。我注意到错误中引用的2行每次调用另一个方法,但它是Zend代码所以我不想改变它。
它仅在会话到期后发生,而不是在我从数据库中删除包含会话信息的行时发生。发生这种情况后,当我查看表时,我注意到除了数据列之外,表中仍然存在该行。
id name modified lifetime data
[random string] [session name] 1468587768 1440 -
因此看起来read()方法检查表中包含id和name的行,并找到该行,然后调用destroy(),它调用read()。我该如何解决这个问题?
另外,刷新页面可以解决用户的问题,但我不希望代码在用户处抛出异常并强制他们刷新页面。
答案 0 :(得分:0)
这对我有用:创建一个扩展DbTableGateway的类并修改其destroy方法以检查是否存在行而不是调用read()函数。然后使用该类而不是DbTableGateway。
所以这里是新的保存处理程序类的代码:
id
以下是您如何更换DbTableGateway:
class MySessionSaveHandler extends DbTableGateway
{
/**
* Destroy session
*
* @param string $id
* @return bool
*/
public function destroy($id)
{
// I removed "read" to prevent an infinite loop, and am using the first line of "read" instead to check if the row exists
$rows = $this->tableGateway->select([
$this->options->getIdColumn() => $id,
$this->options->getNameColumn() => $this->sessionName,
]);
if (! (bool) $rows) {
return true;
}
return (bool) $this->tableGateway->delete([
$this->options->getIdColumn() => $id,
$this->options->getNameColumn() => $this->sessionName,
]);
}
}