【问题标题】:PDO Database class not stopping at catching exceptionPDO 数据库类不会在捕获异常时停止
【发布时间】:2015-10-27 16:09:20
【问题描述】:

我在 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;
    }
}

【问题讨论】:

  • 向我们展示您实例化此类对象的片段。
  • 我确实要求对象初始化并使用片段。不适用于完整的课程描述。你做的事情$DB = new DB;
  • 它是通过 DB::getInstance();" 在大部分代码下调用的。 这正是我需要帮助你的。将页面片段发布到你做那些带来问题的电话。
  • because its meant to be singleton 我不确定你这里有单身人士。

标签: php mysql database pdo


【解决方案1】:

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

【讨论】:

  • 你的意思是改变 try 只包括一个或另一个?
  • 我发现了我的问题......我的第一行 catch `Log::Error('');' ....这已记录在数据库中,因此每次尝试记录错误时它都会无限循环尝试连接。感谢您的帮助。
【解决方案2】:

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

【讨论】:

  • 这个错误是由错误的密码引起的,我试图弄清楚为什么当它无法进入数据库时​​它没有停止。这是一个依赖于数据库的网站,所以在一个完美的场景中,我可以让它停止并向用户显示错误
  • 对不起,我主要关注的是致命错误,这必须在脚本被杀死之前发生。作为测试,尝试增加内存说 ini_set('memory_limit','16M');试试 16,24,32.... 这应该放在执行脚本上。同样,我怀疑您的服务器在完成脚本处理之前内存不足。
  • 在我的 PHP ini 中,它已经设置为 ; Maximum amount of memory a script may consume (128MB) ; http://php.net/memory-limit memory_limit=128M,我将尝试增加它
  • memory_limit=1024M,我在错误日志中获得了 574 个新条目。在 2048 我得到 761。我想我在某个地方遇到了问题,它一直在尝试。
  • 我发现了我的问题......我的第一行 catch `Log::Error('');' ....这已记录在数据库中,因此每次尝试记录错误时它都会无限循环尝试连接。非常感谢您的帮助。
【解决方案3】:

问题出现在“Log::error();”中

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-27
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多