2

在运行 PHPUnit 测试时,会创建很多连接但没有关闭。我可以看到这个

mysql> show processlist;

在我的数据库类中,我通过实现 PHPUnit_Extensions_Database_TestCase#getConnection() 创建了一个数据库连接。

我确保在拆解中连接关闭。见片段:

<?php

abstract class My_Tests_DatabaseTestCase extends \PHPUnit_Extensions_Database_TestCase
{

    static private $pdo = null;
    private $conn = null;

    /**
     * @throws RuntimeException
     * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
     */
    final public function getConnection()
    {
        $iniFilePath = __DIR__ . '/../../../db-config.ini';
        $iniFile = parse_ini_file($iniFilePath, true);

        $dsn = "mysql:dbname=".$iniFile['phpunit']['dbname'].";host=".$iniFile['phpunit']['host'];
        if ( $this->conn === null ) {
            if ( self::$pdo == null ) {
                self::$pdo = new \PDO($dsn, $iniFile['phpunit']['user'], $iniFile['phpunit']['password']);
            }
            $this->conn = $this->createDefaultDBConnection(self::$pdo, $iniFile['phpunit']['dbname']);
        }
        return $this->conn;
    }

    protected function getSetUpOperation()
    {
        return new \PHPUnit_Extensions_Database_Operation_Composite(array(
            new \TestsExtensions\TruncateDatabaseOperation(),
            \PHPUnit_Extensions_Database_Operation_Factory::INSERT()
        ));
    }

    protected function getTearDownOperation() {
        return \PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE();
    }

    protected function setUp()
    {
        parent::setUp();
        $em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
        $em->clear();
    }

    protected function tearDown()
    {
        parent::tearDown();
        $em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
        $em->getConnection()->close();
        if ($this->conn) {
            $this->conn->close();
        }
    }
}

调试显示连接已关闭,但进程列表显示它们的状态为“睡眠”。连接数量会增加,直到出现“连接太多”错误。

我不想增加连接数。我想关闭连接。

我可以修改什么来实现这一点?

4

1 回答 1

6

PDO 连接管理的片段:

成功连接到数据库后,PDO 类的实例将返回到您的脚本。该连接在该 PDO 对象的生命周期内保持活动状态。要关闭连接,您需要通过确保删除对它的所有剩余引用来销毁该对象——您通过将 NULL 分配给保存该对象的变量来做到这一点。如果您没有明确地这样做,PHP 将在您的脚本结束时自动关闭连接。

不要在拆解中存储 PDO 或将其设置为 null:

消除static private $pdo = null;

或者

protected function tearDown()
{
    parent::tearDown();
    $em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
    $em->getConnection()->close();
    if ($this->conn) {
        $this->conn->close();
    }
    self::$pdo = null;
}

如果要将 PDO 传递到 PHPUnit DB 连接,我认为不需要存储它

于 2013-06-14T21:38:40.370 回答