gpt4 book ai didi

PHP ZF2 Mysql 已经消失

转载 作者:行者123 更新时间:2023-11-29 06:27:03 25 4
gpt4 key购买 nike

您好,我有一个处理来自 rabbitmq 的请求的 php 守护进程

一天后,由于错误 MySQL 已经消失,它无法再执行。

PHP Warning:  PDOStatement::execute(): MySQL server has gone away in /var/www/daemon/www/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php on line 239
PHP Warning: PDOStatement::execute(): Error reading result set\'s header in /var/www/daemon/www/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php on line 239

我没有使用 doctrine,而是将我的\Zend\Db\Adapter\Adapter 发送到具有以下函数的数据库包装器类。

public static function executeScalar($statement, $parameters, \Zend\Db\Adapter\Adapter $dbAdapter)
{
$dbResult = new DbResult();
if (! $statement) {
$dbResult->addError('No statement given');
return $dbResult;
}

$stmt = $dbAdapter->createStatement();
$stmt->prepare($statement);

foreach ($parameters as $key => &$param) {
$stmt->getResource()->bindParam($key + 1, $param[0], $param[1]);
}

try {
$result = $stmt->execute();
$dbResult->setResult($result);
} catch (\Zend\Db\Adapter\ExceptionInterface $e) {
$dbResult->addError('DB Error');
$message = $e->getPrevious() ? $e->getPrevious()->getMessage() : $e->getMessage();
$dbResult->addError($message);
} catch (\Zend\Db\Adapter\Exception $e) {
$dbResult->addError('DB Error');
$dbResult->addError($e->getMessage());
} catch (\PDOException $e) {
$dbResult->addError('DB Error');
$dbResult->addError($e->getMessage());
} catch (\Exception $e) {
$dbResult->addError('DB Error');
$dbResult->addError($e->getMessage());
}
$stmt->getResource()->closeCursor();

return $dbResult;
}

DbResult是我自己的db结果包装类,主要检查是否返回空,错误是什么,有多少行等。

这是我的 database.local.php 配置

return array(
'service_manager' => array(
'factories' => array(
'mysql' => function ($sm)
{
return new Zend\Db\Adapter\Adapter(array(
'driver' => 'PdoMysql',
'hostname' => 'localhost',
'database' => 'daemon',
'username' => 'daemon',
'password' => 'password',
'driver_options' => array(
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => true,
\PDO::MYSQL_ATTR_LOCAL_INFILE => true
)
));
},
)
)
)

所以每次我想执行一个 sql 时,我都会在 Controller 或任何其他类中执行此操作(只是一个例子)

$service = $this->getServiceLocator();
$dbAdapter = $service->get('mysql');
$get = \Db\Database::executeScalar('SELECT * FROM mytable WHERE id <= ?', array(10), $dbAdapter);

我似乎无法捕捉到警告,有没有办法强制重新连接,或者我可能只是在每次请求后断开连接?

这能处理错误吗?对于每个新请求,我都会这样做

$dbAdapter->getDriver()->getConnection()->connect();

在请求结束时我这样做

$dbAdapter->getDriver()->getConnection()->disconnect();

最佳答案

是的,我检查了持久连接选项,但我也不喜欢它。

我发现了问题,它是由 mysql 服务器在“等待超时”后关闭空闲连接引起的。当 mysql 关闭空闲连接时,PDO 将不会收到任何事件,因此下次您发起查询时它将返回 Mysql has gone away 错误。

对于 http 请求,这是可以接受的,因为在服务器响应请求后,它将停止/退出 php 执行,从而关闭所有与数据库的连接。

对于守护进程/服务,这是 Not Acceptable ,因为大部分时间它都在等待客户端请求(空闲)。我的解决方案是每次完成处理客户端请求时关闭连接。例如:

while (true) {
//listen to rabbitmq queue
//...

//do something base on client request from rabbitmq queue
//...

//close the connection whether it use database or not
//connection will be reconnected when we call $service->get('mysql');
$service = $this->getServiceLocator();
$dbAdapter = $service->get('mysql');
$dbAdapter->getDriver()->getConnection()->disconnect();
}

关于PHP ZF2 Mysql 已经消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30364507/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com