Last active
January 9, 2025 12:21
-
-
Save extraordinaire/4135119 to your computer and use it in GitHub Desktop.
Reconnectable PDO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class ReconnectingPDO | |
{ | |
protected $dsn, $username, $password, $pdo, $driver_options; | |
public function __construct($dsn, $username = "", $password = "", $driver_options = array()) | |
{ | |
$this->dsn = $dsn; | |
$this->username = $username; | |
$this->password = $password; | |
$this->driver_options = $driver_options; | |
} | |
public function __call($name, array $arguments) | |
{ | |
try { | |
$this->connection()->query("SHOW STATUS;")->execute(); | |
} catch(\PDOException $e) { | |
if($e->getCode() != 'HY000' || !stristr($e->getMessage(), 'server has gone away')) { | |
throw $e; | |
} | |
$this->reconnect(); | |
} | |
return call_user_func_array(array($this->connection(), $name), $arguments); | |
} | |
protected function connection() | |
{ | |
return $this->pdo instanceof \PDO ? $this->pdo : $this->connect(); | |
} | |
public function connect() | |
{ | |
$this->pdo = new PDO($this->dsn, $this->username, $this->password, (array) $this->driver_options); | |
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
return $this->pdo; | |
} | |
public function reconnect() | |
{ | |
$this->pdo = null; | |
return $this->connect(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this, got me started in the right direction. However as was mentioned MySQL server has gone way is a PHP Fatal Error so it breaks the try catch. To get around this issue I set four more properties:
Set
$this->connectStartTime = time();
in theconnect()
method, and do the following in the__call()
method.I know this doesn't address some of the other users comments about restoring transactions, but in my use case this wasn't an issue. I just needed PDO to attempt to reconnect if there was a delay from a third party API.