简体   繁体   中英

PDO: MySQL server has gone away, can't catch exception

General Description
I'm working a chatsystem using websockets (Ratchet). The chat works perfectly fine, but I'm having some issue with my database class.

The Problem
During development, the chatsystem obviously isn't visited a lot. This causes the MySQL server to close the connection eventually. To solve that issue, I've written some exception handlers to reconnect to the MySQL server. But somehow this doesn't work. Here's the bare minimum of how my code looks like:

<?php

Class Database {
    private $host = DB_HOST;
    private $user = DB_USER;
    private $pass = DB_PASS;
    private $dbname = DB_NAME;

    private $dbh;
    private $error;

    private $stmt;

    public function __construct(){

        if($this->dbh === null){
            $this->reconnect();
        }
    }

    private function reconnect(){
        // Set DSN
        $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
        // Set options
        $options = array(
            PDO::ATTR_PERSISTENT    => false,
            PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
        );
        // Create a new PDO instanace
        try{
            $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
        }
        // Catch any errors
        catch(PDOException $e){
            $this->error = $e->getMessage();
            return $this->error;
        }
    }

    /* Execute query */
    public function execute(){
        try{
            return $this->stmt->execute();
        }
        catch(PDOException $e){
            $this->reconnect();

            try{
                return $this->stmt->execute();
            }
            catch(PDOException $e){
                $this->error = $e->getMessage();
                return $this->error;
            }
        }
    }

Of course there are many more simular methods, but those are not important.

The error I'm being presented with is the following:

PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away in /var/www/clients/client1/web4/web/src/Pdo.php:43 Stack trace:
/var/www/clients/client1/web4/web/src/Pdo.php(43): PDOStatement->execute()

That error points to return $this->stmt->execute(); in the execute() method above.

  1. How is it possible that the error is telling me "Uncaught PDOException" while I'm clearly catching it?
  2. How is the MySQL server even able to disconnect while I'm not using a persistent connection? PDO::ATTR_PERSISTENT => false,

As determined in the comments, you're running this code within another namespace. This means that catch (PDOException $e) is actually catch (\\Your\\Namespace\\PDOException $e) so will not work. You'll either need to prefix the class with a leading backslash to put it in the global namespace:

catch(\PDOException $e){
    $this->error = $e->getMessage();
    return $this->error;
}

Or use the class at the beginning of your code.

use \PDOException;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM