[PDO] Exception du constructeur ?

ViPHP
xTG
ViPHP | 7331 Messages

12 sept. 2011, 15:56

Bonjour à toutes et à tous,

il est indiqué dans le constructeur de la class PDO qu'elle renvoie une Exception en cas d'impossibilité de connexion.
Sauf que dans mon cas... Bah je peux même pas le tester !

Je rentre de faux identifiants (volontairement) et je le laisse mouliner.
Le script s'arrête sur deux warnings (relatifs à l'impossibilité de connexion) et un fatal error (maximum execution time)...

Alors certes j'ai mon résultat, mais c'est moche comme affichage... Mais du fait du fatal error je me trouve bloqué.
Auriez-vous une idée pour me dépêtrer de ce bordel ?
Mon but est de tester l'existence du serveur, la validité des identifiants et de la base de donnée.

Eléphant du PHP | 245 Messages

12 sept. 2011, 16:44

peut être que PDO définit un time out par défaut pour la tentative de connexion au serveur et que celui ci est supérieur au time out du php.ini pour servir la pageet que du coup la fatal error "max execution time" sorte avant l'avertissement PDO

Il faut peut être tester en set_time_limit(0) et regarder la méthode : PDO::setAttribute avec PDO::ATTR_TIMEOUT

http://php.net/manual/fr/pdo.setattribute.php
■PDO::ATTR_TIMEOUT: Précise la durée de timeout en secondes. Tous les pilotes ne supportent pas cette option et sa signification peut différer en fonctions des pilotes. Par exemple, sqlite attendra pendant cette période pour obtenir un verrou en écriture sur le fichier, mais les autres pilotes considèreront ceci comme un timeout de connexion ou de lecture. Requiert int.

ViPHP
xTG
ViPHP | 7331 Messages

12 sept. 2011, 18:38

C'est bien ce que je pensais, mais le souci est que dans le cas où on ne peut toucher au temps d'exécution bah... C'est râpé !
Car PDO::setAttribute() intervient après l'instanciation, cette dernière me posant le problème déjà énoncé. :(

Mais certaines configuration peuvent servir dans l'instanciation (mais jamais trouvé dans la doc la liste réelle...).
Donc je vais tester cette constante à tout hasard. :)

Edit: bon bah c'est pas génial...
Cet attribut doit pas être pris en compte, toujours le timeout du php.ini
Le pire c'est qu'après test c'est juste le test de port/adresse qui foire tout... (ça me freeze mon Apache jusqu'au fatal error... xD)
Identifiant ou bdd ça répond via Exception dans la seconde !
Mais le souci c'est que je peux vraiment faire un test de port ou d'url... Car même si le serveur répond quelque chose c'est pas dit que ça soit un accès à une base de données...

ViPHP
ViPHP | 3607 Messages

13 sept. 2011, 10:55

Si je me rappel bien, il faut préciser à PDo qu'on veut récupérer des exceptions:
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ?

Les exemples donnés ici : http://www.php.net/manual/fr/pdo.connections.php
ne fonctionnent pas ?

ViPHP
xTG
ViPHP | 7331 Messages

13 sept. 2011, 11:47

Malheureusement cette option ne peut être appliquée au constructeur, elle ne s'utilise qu'avec PDO::setAttribute(). :(
// Tentative de connexion au serveur de base de données
try {
	$db = new PDO($dsn, $_POST['sgbd_username'], $_POST['sgbd_mdp'], array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_TIMEOUT => 10));
} catch (PDOException $e) {
	// Tentative échouée
	$_SESSION['etape']--;
	$erreur['glob'][] = 'Impossible de se connecter au serveur de base de données.';
}
Ceci me conduit au même comportement que sans option.

ViPHP
ViPHP | 5462 Messages

13 sept. 2011, 13:51

essaye de modifier la valeur de stream_set_timeout

Eléphant du PHP | 121 Messages

13 sept. 2011, 17:08

Bizarre bizarre... j'utilise le même genre de code et lorsque je donne n'importe quoi comme identifiant ou mot de passe j'ai bien une exception PDOException que je peux attraper sans problème : https://github.com/ICanBoogie/ICanBoogi ... s.php#L105

Tu peux tester ton code dans un autre environnement ?

Sinon, tu as essayé sans "PDO::ATTR_TIMEOUT => 10" ?

ViPHP
xTG
ViPHP | 7331 Messages

13 sept. 2011, 18:52

Bizarre bizarre... j'utilise le même genre de code et lorsque je donne n'importe quoi comme identifiant ou mot de passe j'ai bien une exception PDOException que je peux attraper sans problème : https://github.com/ICanBoogie/ICanBoogi ... s.php#L105

Tu peux tester ton code dans un autre environnement ?

Sinon, tu as essayé sans "PDO::ATTR_TIMEOUT => 10" ?
Essayes avec un serveur ou un port bidon. ;)
Qu'apporterai que j'enlève ou non cette constante puisqu'elle n'est pas interprétée ? (cf le topic et mes réponses)
Je n'ai pas d'autre environnement à disposition.

@Stealth35 : j'avais ça en réserve mais je préfère garder de côté en attendant de trouver mieux.
Car une connexion socket indique pas que c'est un sgbd, on peut très bien n'avoir qu'un serveur web derrière cette adresse et ce port.
Auquel cas le test sera faux et lors de l’instanciation de PDO on retombera sur le même problème.

Eléphant du PHP | 121 Messages

13 sept. 2011, 19:39

Bon j'ai essayé avec "unix_socket=/madonna/":

Code : Tout sélectionner

SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/madonna/' (2)
Avec "host=madonna":

Code : Tout sélectionner

SQLSTATE[HY000] [2005] Unknown MySQL server host 'madonna' (1)
Avec mon routeur en host "host=192.168.0.1":

Code : Tout sélectionner

SQLSTATE[HY000] [2013] Lost connection to MySQL server at 'reading initial communication packet', system error: 111
Avec "dbname=madonna":

Code : Tout sélectionner

SQLSTATE[42000] [1049] Unknown database 'madonna'
En ce qui concerne "port", quelque soit la valeur ça marche toujours... bizarre.

Toutes les exceptions furent lancées sans délai sur mon serveur Ubuntu 11.04 (php5.3.5).

Alors, est-ce qu'on ne pourrait pas contourner le problème ? Si ton code sert à tester la validité d'une connexion ou d'une base, pourquoi ne pas déplacer le code dans un script auxiliaire, disons "test-db.php" ? Tu places les variables dont tu as besoin pour établir la connexion en session et tu appelles ce script avec cURL en lui passant de quoi récupérer la session. Est-ce que ça pourrait suffire ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

13 sept. 2011, 20:57

salut,

j'ai testé avec madonna j'ai bien l'exception mais il y a aussi deux beaux warning avant
Warning: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Hôte inconnu. in H:\web\docRoot\hitzerod.php on line 3

Warning: PDO::__construct(): [2002] php_network_getaddresses: getaddrinfo failed: Hôte inconnu. (trying to connect via tcp://Consolas:3306) in H:\web\docRoot\hitzerod.php on line 3

Erreur !!!!!!
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Hôte inconnu.
A voir avec le repport d'erreur !

pour xTG heu un gestionnaire d'erreur perso :mrgreen:
Il en faut peu pour être heureux ......

ViPHP
xTG
ViPHP | 7331 Messages

13 sept. 2011, 20:58

Ouep j'avais aussi ça sous la main au cas où. Un peu barbare mais bon...
Le truc qui me gêne c'est suivant les hébergements curl peut être désactivé.

Cependant de voir que chez toi tu as bien le retour d'erreur, cela m'intéresserai du coup de trouver quelle est la configuration qui fait foirer mon truc...

@Moogli : c'est pas les warnings qui me posent problème mais le fatal error contre lequel je peux rien faire. :P

devlop78
Invité n'ayant pas de compte PHPfrance

16 sept. 2011, 15:03

xtg je ne sais pas quel est le but réel de cette manip (à priori l'adresse que tu fournis, si elle est bonne, fonctionne), mais voilà je pense à deux trucs :

- Test préliminaires (Curl comme cité, et tu as répondu bof, mais peut etre d'autres);
- register_shutdown_function pour tester dernière erreur (E_ERROR), et balancer un beau message d'erreur d'excuse (de toutes façons, sur la plupart des appli, pas de base de données = pas de contenu = même en gérant l'exception, que lui dire et quoi afficher comme compensateur (des photos de glaces au chocolat ?)).

Enfin, j'dis ça ... j'dis rien ...

Perso :

register_shutdown_function et set_error_handler balacent une exception donc quoiqu'il arrrive c'est toujours au pire le gestionnaire d'exception le plus à l'arrière qui traite le problème.

ViPHP
xTG
ViPHP | 7331 Messages

16 sept. 2011, 17:06

C'est pour un script d'installation en fait.
Mais mon problème n'était pas de capter l'erreur en soit ou de tester la connexion (il existe moultes méthodes comme on l'a vu) mais de me débarrasser de ce fatal error.
A priori cela doit venir de ma configuration de PHP. Pas encore trouvé quoi mais je trouverai bien un jour...
Et j'ai au moins la certitude maintenant que cela ne ferra pas cela sur tout serveur.