le blog technique de la team weedo
Avoir accès à un objet PDO n'est pas suffisant pour être certain d'avoir une connexion à une bdd. Il arrive de passer une requête et d'obtenir l'erreur :
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' in…
Pour obtenir cette erreur, vous pouvez faire le test suivant :
$pdo = new PDO($dsn, $user, $password); echo get_class ($pdo); // On a bien un objet PDO $pdo->query('select 1'); // ça passe sleep(20); // Vous avez 20 secondes pour killer manuellement la connexion mysql. Faites-le pour les besoins du tests, echo get_class ($pdo); // On a toujours un objet PDO, mais cet objet n'est pas informé que la connexion correspondante a été killée, ce qu'on va voir tout de suite : $pdo->query('select 1'); // !! ça casse : Erreur MySQL server has gone away. Pourtant, on avait bien un objet PDO
Les raisons possibles de cette erreurs sont nombreuses : http://dev.mysql.com/doc/refman/5.0/en/gone-away.html
En plus de/plutôt que/en attendant de résoudre le problème, j'ai trouvé 2 méthodes (assez proche) pour contourner le problème : On tente la connexion avec notre vieille connexion pdo, et si on obtient une erreur, on créé un nouvel objet pdo tout neuf.
Méthode 1
$sql = 'SELECT count(*) FROM `TABLE`;'; for ($i = 1; $i <= 2; $i++) { try { $nb = $pdo->query($sql)->fetchColumn(); if (is_int($nb)) { // C'est bon, ma vieille connexion a fonctionné. break; } } catch (PDOException $e) { //Oups, j'ai une erreur de connexion if ($i == 1) { // C'est la première fois ? OK, je recréé une connexion. $pdo = new PDO($dsn, $user, $password); } else { // C'est la 2eme fois ? OK, c'est mort. $nb = "(nombre inconnu)"; echo 'PDO Connection failed: ' . $e->getMessage().'. '; } } }
Méthode 2
// Je test si ma vieille connexion est OK avec une requête toute simple try { $pdo->query('select 1;') //C'est bon; } catch (PDOException $e) { //Oups, j'ai une erreur de connexion // Je recréé une connexion. $pdo = new PDO($dsn, $user, $password); } // Ici j'ai plus de chance d'avoir un objet pdo viable que si je n'avais pas fait le petit try/catch au-dessus => Je fais ma requête $sql = 'SELECT count(*) FROM `TABLE`;'; $nb = $pdo->query($sql)->fetchColumn();
Comme d'hab, si quelqu'un a mieux, ce que j'espère, je suis preneur !
Comments 0 Comments