PDO数据库类不会在捕获异常时停止

时间:2015-10-27 16:09:21

标签: php mysql database pdo

我在PDO数据库类中有以下代码

/**
 * Class DB
 */
class DB{
    /**
     * @var DB The one and only instance of this class;
     */
    private static $theOneAndOnly = null;
    /**
     * @var array
     */
    private static $transactionalOptions = array( PDO::ATTR_AUTOCOMMIT => false, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC );
    /**
     * @var array
     */
    private static $nonTransactionalOptions = array( PDO::ATTR_AUTOCOMMIT => true, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC );
    /**
     * @var PDO
     */
    private $transactionalDatabase = null;
    /**
     * @var PDO
     */
    private $nonTransactionalDatabase = null;
    /**
     * @var bool
     */
    private $isConnected = false;

    /**
     * Initializes the connections to the database. One connection for transaction based operations and one connection
     * for non-transactional operations;
     */
    private function __construct(){
        if($this->isConnected() !== true){
            //connect
            if($this->connect() !== true){
                //connection failed
                exit( 'An internal error occurred. Please contact Keyfort support:' );
            }
        }
    }

    /**
     * @return bool
     */
    public function isConnected(){
        return $this->isConnected;
    }

    /**
     * @return bool
     */
    public function connect(){
        try{
            $this->transactionalDatabase = new PDO(Config::DB_TYPE . ':host=' . Config::DB_HOST . ';dbname=' . Config::$DB_NAME, Config::$DB_USER, Config::$DB_PASS, self::$transactionalOptions);
            $this->nonTransactionalDatabase = new PDO(Config::DB_TYPE . ':host=' . Config::DB_HOST . ';dbname=' . Config::$DB_NAME, Config::$DB_USER, Config::$DB_PASS, self::$nonTransactionalOptions);

            $this->isConnected = true;

            return true;
        } catch(PDOException $exception){
            Log::error('Initializing the database connections failed:' . $exception->getTraceAsString());
            die();
            //return false;
        }
    }

    /**
     * @return DB
     */
    public static function &getInstance(){
        if(self::$theOneAndOnly === null){
            self::$theOneAndOnly = new self();
        }

        return self::$theOneAndOnly;
    }

    public static function ParamMultiple($key){
        return self::Param($key) . ', ';
    }

    public static function Param($key){
        return ':' . $key;
    }

    /**
     * Close all connections;
     */
    public function __destruct(){
        $this->disconnect();
    }

    /**
     * @return void
     */
    public function disconnect(){
        $this->transactionalDatabase = null;
        $this->nonTransactionalDatabase = null;
        $this->isConnected = false;
    }

    /**
     * @return PDO
     */
    public function &getTransactional(){
        if($this->isConnected() !== true){
            $this->connect();
        }

        return $this->transactionalDatabase;
    }

    /**
     * @return PDO
     */
    public function &getBasic(){
        if($this->isConnected() !== true){
            $this->connect();
        }

        return $this->nonTransactionalDatabase;
    }
}

通过DB :: getInstance();

调用它

第一次调用时,如果错误则不会“死”。

我最终得到了

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in C:\path\to\class\db.php on line 64

第64行是$ this-> transactionalDatabase行。

它会在我的错误日志中记录异常(如在catch中)。

我正在弄清楚为什么它不会“死”,我已经尝试了很多东西,我想知道它是否可以在尝试中启动2个PDO?

[编辑] 我目前使用错误的数据库用户密码运行代码。所以我知道错误是由什么引起的(当我输入正确的密码时它工作正常),我只是不明白它为什么不处理catch中的die()。

使用片段:

public static function GetByUsername($username){
    $db = DB::getInstance();
    $dbh = $db->getBasic();

    $sql = 'SELECT * FROM ' . self::TABLE_NAME . ' WHERE ' . self::KEY_USERNAME . ' = ' . DB::Param(self::KEY_USERNAME);

    $statement = $dbh->prepare($sql);

    $statement->bindValue(DB::Param(self::KEY_USERNAME), $username);

    if($statement->execute() === true){
        $rawUser = $statement->fetch();
        if($rawUser === null){
            return null;
        } else {
            return self::CreateFromSelectResult($rawUser);
        }
    } else {
        Log::error("Fetching user by username failed:" . print_r($dbh->errorInfo(), true));

        return null;
    }
}

3 个答案:

答案 0 :(得分:1)

尝试使用transactionalDatabase或nonTransactionalDatabase,它应该可以解决问题。

答案 1 :(得分:1)

确保您的/ tmp文件夹有空间来缓存查询。

答案 2 :(得分:0)

问题出在" Log :: error();"

日志:error()也尝试使用数据库。

所以问题是在达到die()行之前开始的无限循环。