扩展Phalcon \ Db \ Adapter \ Pdo \ Mysql时连接太多

时间:2018-01-18 11:21:33

标签: php mysql exception pdo phalcon

每次查询函数返回Phalcon\Db\Adapter\Pdo\Mysql时,我都尝试扩展false以创建日志。

即使我没有在parent::__construct中创建任何新连接,但我得到以下异常:

Fatal error: Uncaught PDOException: SQLSTATE[08004] [1040] Too many connections in ...Internal/Database/Mysql.php:14 Stack trace: #0 [internal function]: PDO->__construct('mysql:adapter=M...', '...', '...', Array) #1 [internal function]: Phalcon\Db\Adapter\Pdo->connect(Array) #2  .../Internal/Database/Mysql.php(14): Phalcon\Db\Adapter\Pdo->__construct(Array) #3 .../apps/bootstrap/app.php(378): Internal\Database\Mysql->__construct(Array) #4 [internal function]: Closure->{closure}() #5 [internal function]: Phalcon\Di\Service->resolve(NULL, Object(Phalcon\Di\FactoryDefault)) #6 .../apps/bootstrap/core_services.php(7): Phalcon\Di->get('logs') #7 [internal function]: Closure->{closure}() #8 [internal function]: Phalcon\Di\Service->resolve(NULL, Object(Phalcon\Di\FactoryDefault)) #9 .../apps/libs/Internal/Database/Mysql.php(15): Phalcon\Di->get('logger') #10 .../apps/bootstrap/app.php(37 in .../apps/libs/Internal/Database/Mysql.php on line 14

代码:

namespace Internal\Database;

use Phalcon\Db\Adapter\Pdo\Mysql as PhalconMysql;
use Phalcon\Di;

class Mysql extends PhalconMysql
{
    public $isLogger = false;

    public function __construct(array $descriptor)
    {
        parent::__construct($descriptor);
        $this->oLogger = Di::getDefault()->get('logger');
    }

    public function query($sqlStatement, $bindParams = null, $bindTypes = null)
    {
        $oResult = parent::query($sqlStatement, $bindParams, $bindTypes);
        if ($oResult === false && $this->isLogger === false) {
            $trace = debug_backtrace();
            $aCaller = array_shift($trace);
            $sFile = $aCaller['file'];
            $sLine = $aCaller['line'];
           $this->oLogger->error('MySQL query failed. File: ' . $sFile . ', Line: ' . $sLine, ['error' => $this->getErrorInfo()]);
    }
        return $oResult;
    }
}

触发错误的行是parent::__construct($descriptor);

我所做的唯一其他更改是将Phalcon\Db\Adapter\Pdo\Mysql替换为Internal\Database\Mysql。所有连接的创建方式与我使用Phalcon\Db\Adapter\Pdo\Mysql时的方式相同。

我查看了Phalcon\Db\Adapter\Pdo\Mysql的父类。我看到创建连接的唯一地方是here

我非常感谢你对这个问题的帮助。

4 个答案:

答案 0 :(得分:1)

在phalcon中扩展类是不正确的,它实际上与其他php扩展交互。很了解它。

我建议的简单方法是覆盖Mvc / Model类作为例如。 ModelCommon或BaseModel,并实现Model::initializeModel::afterFetch

但是正确的方法是使用Phalcon开发的事件机制。诀窍是附加到beforeQuery和/或afterQuery事件。

快捷方式,在DI中完成:

$di->set('db', function() use ($di) {
    $config = $di->getConfig();
    $connection = new \Phalcon\Db\Adapter\Pdo\Mysql([
        // ...
    ]);

    $eventsManager->attach('db', function($event, $connection, $params) use ($config) {

        if ($event->getType() == 'beforeQuery') {
            // ...
        }

        if ($event->getType() == 'afterQuery') {
            // ...
        }
    });

    $connection->setEventsManager($eventsManager);
    return $connection;
});

答案 1 :(得分:0)

看起来该模块正在尝试多次连接到数据库。也许请确保在Module.php

中初始化一次数据库服务

答案 2 :(得分:0)

在$ di

中声明db时,也许你可以将服务分享为共享
$di->setShared('db', function() {
    // return your db instance
});

答案 3 :(得分:0)

问题解决了,虽然我仍然不明白为什么它首先发生。

记录器记录到数据库,但由于它从Di中取出,我认为它重用了现有的连接。从构造函数中删除该行,并在调用记录器之后将其放置正确解决了问题。