PDO catch PDOException не работает при построении

Я видел варианты этого кода повсюду, включая много сообщений SO:

class db extends PDO { public function __construct( $dbconf ) { $options = array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => $dbconf['persist'] ? true : false ); try { parent::__construct('mysql:host='. $dbconf['dbhost'] .';port=3306;dbname='. $dbconf['dbname'] .';' , $dbconf['dbuser'], $dbconf['dbpass'], $options); } catch (PDOException $e) { $this->myerror( $e->getMessage() ); // echo 'Connection failed ... '. $e->getMessage(); } } ... private function myerror( $error ) { echo 'Connection failed ... '. $error; } } 

Класс создается с помощью $db = new db( $config ); , и он отлично работает, если соединение действительно, но кажется, что PDOException самом деле не работает, если соединение терпит неудачу. catch полностью не выполняет функцию $this->myerror(...) ! Вместо полезного $e->getMessage() котором говорится: «Connection failed … Access denied for user blah», я получаю PHP Fatal error: Call to a member function myerror() on a non-object in /.../lib/pdo.class.php on line 16 .

Если я прокомментирую первую строку в catch и раскомментирую echo , она работает так, как ожидалось, сообщая причину ошибки соединения. Почему сообщение будет доступно в catch, но не в простой myerror класса myerror ?

Это сообщение … PHP, PDO и Исключения … кажется применимым, но не объясняет многое. Является ли catch (PDOException $e) устаревшим или дисфункциональным при определенных обстоятельствах? Как я могу заставить это работать?

Причина в том, что PDO::__construct только создает object при успешном соединении. Поэтому, когда вы вызываете родительский конструктор, и он терпит неудачу, ваш объект больше не существует. Вы должны использовать self::myerror() для доступа к функции ошибки статически в этом случае.

Не должно быть функции myerror() вообще. Уровень базы данных вряд ли нужен, это собственный обработчик ошибок. И конструктор должен быть

 public function __construct( $dbconf ) { $dsn = "mysql:"; $dsn .= "host=". $dbconf['dbhost'].";"; $dsn .= "dbname=". $dbconf['dbname'].";"; $dsn .= "port=". $dbconf['dbport'].";"; $dsn .= "charset=".$dbconf['dbcharset']; $options = array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES '.$dbconf['charset'], PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => (bool)$dbconf['persist'], ); parent::__construct($dsn, $dbconf['dbuser'], $dbconf['dbpass'],$options); }