PDO et erreur
Le
unbewusst.sein

je simule volontairement une erreur en appellant une base de donnée qui
n'existe pas en tant que fichier.
un fichier de base de donnée vide est créé, normal.
Mais ensuite j'envoie une requête sur cette base vide :
$res=$db->query('SELECT ROWID, * FROM categories');
try{
while($row=$res->fetch()){
print_r($row);
echo "<br />";
}
}catch (PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}
Et, bien sûr, j'ai une erreur :
Fatal error: Call to a member function fetch() on a non-object in
/Users/yt/Sites/landp/landp-pdo-test.php on line 6
malgré le try / catch qui entoure la ligne fautive :
while($row=$res->fetch()){
D'où, ma question, comment gérer l'erreur dans ce cas ?
--
« Dites nous ce dont vous avez besoin ,
on vous expliquera comment vous en passer ! »
(Coluche)
n'existe pas en tant que fichier.
un fichier de base de donnée vide est créé, normal.
Mais ensuite j'envoie une requête sur cette base vide :
$res=$db->query('SELECT ROWID, * FROM categories');
try{
while($row=$res->fetch()){
print_r($row);
echo "<br />";
}
}catch (PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}
Et, bien sûr, j'ai une erreur :
Fatal error: Call to a member function fetch() on a non-object in
/Users/yt/Sites/landp/landp-pdo-test.php on line 6
malgré le try / catch qui entoure la ligne fautive :
while($row=$res->fetch()){
D'où, ma question, comment gérer l'erreur dans ce cas ?
--
« Dites nous ce dont vous avez besoin ,
on vous expliquera comment vous en passer ! »
(Coluche)
Le 10/11/2011 10:25, Une Bévue a écrit :
Tu n'as pas testé le code de retour de query, avant de l'utiliser
comme si c'était un PDOStatement. C'est mal.©
Il suffit de tester les codes d'erreur prévus et signalés dans la doc.
Valeurs de retour
PDO::query() retourne un objet PDOStatement, ou FALSE si une erreur
survient.
Cordialement,
--
Olivier Miakinen
Je ne connais rien au PHP et encore moins pour ses appels à BdD,
if($res=$db->query('SELECT ROWID, * FROM categories'))
try{
non ?
ou bien (en glissant sur l'erreur) :
if(@$res=$db->query('SELECT ROWID, * FROM categories'))
try{
sinon
peut-être
$res=$db->query('SELECT ROWID, * FROM categories');
try{
while(@$row=$res->fetch()){
ou ?
$res=$db->query('SELECT ROWID, * FROM categories');
try{
while($row=$res->@fetch()){
???
Qu'en disent-ils sur le NG du PHP ?
--
Stéphane Moriaux avec/with iMac-intel
Par ailleurs, tu as fait un crosspost avec suivi dans fr.comp.lang.php
sans signaler le suivi, ce qui a trompé SAM qui croyait répondre dans
fciwa. Ce n'est pas très bien non plus... ;-)
[suivi nulle part, c'était juste pour prévenir les lecteurs de fciwa
que les réponses sont sur fclp]
Ah OK, suis-je bête, merci beauc
oup, je vais lire cette littérature...
Mon but est de rendre compatible mon appli entre le php de free qui
n'utilise que PDO et le php sur Mac OS X où je peux utiliser SQLite3
directement.
MAIS, d'après ce que j'ai lu sur un manuel php, les prochaines versions
d'icelui ne permettront la manipulation d'une base qu'à travers PDO, la
gestion directe ne sera plus supportée...
c'est bien vrai ???
Ha! Oui! La honte !
Que vont-ils en penser là-bas ?
Vu!
Personne n'y a encore tenté de corriger mes fantaisies.
--
Stéphane Moriaux avec/with iMac-intel
Ben, finalement, je ne comprends pas ce que tu me dis là ou je ne
comprends pas le manuel, ou pire, les deux...
Je lis :
PDO::query() exécute une requête SQL en appelant une seule fonction,
retourne le jeu de résultats (s'il y en a) retourné par la requête en
tant qu'objet PDOStatement.
à l'adresse :
Ben, c'est bien une "PDOStatement" mon $res=$db->query('SELECT ROWID, *
FROM categories');
je dois dire qu'avant je faisais un :
if($res) {
while($row=$res->fetch()){
...
et que $res était tjs à 1 même quand je provoquait volontairement une
certaine erreur (pas de base en tant que fichier donc pas de table
categories à lire).
Alors que la doc dit :
Valeurs de retour
PDO::query() retourne un objet PDOStatement, ou FALSE si une erreur
survient.
donc je devrais plutôt tester le code de retour de :
car je lis :
PDO::errorCode() retourne uniquement les codes erreurs pour les
opérations exécutées directement sur le gestionnaire de la base de
données. Si vous créez un objet PDOStatement avec la fonction
PDO::prepare() ou la fonction PDO::query() et que vous invoquez une
erreur sur le gestionnaire de requête, PDO::errorCode() ne retournera
pas cette erreur. Vous devez appeler PDOStatement::errorCode() pour
retourner le code erreur pour une opération exécutée sur un gestionnaire
de requête particulier.
à la page :
Donc, si j'ai bien compris, je devrais plutôt faire :
$db=new PDO("sqlite:fichier-qui-n-existe-pas.db");
// le fichier "sqlite:fichier-qui-n-existe-pas.db" est créé,
// mais il est vide de toute table
$res=$db->query('SELECT ROWID, * FROM categories');
if($res)[
while($row=$res->fetch()){
print_r($row);
echo "<br />";
}
} else {
// une erreur c'est produite car $res est à false
// see echo "nPDOStatement::errorCode(): ";
print $res->errorCode();
$info=$res->errorInfo();
print_r($info);
}
C'est ça ?
En fait ce qui était faux, c'était mon :
} catch (PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}
qui n'est valable qu'au niveau de :
$db=new PDO("sqlite:fichier-qui-n-existe-pas.db");
laquelle ligne ne produit pas d'erreur...
avec SQLite, puisque s'il n'existe pas, le fichier est créé.
bon, je poste et je teste ça...
Tout d'abord je précise que je n'ai fait que lire la doc, et qu'il
ne s'agit pas d'une expérience personnelle. Si la doc est fausse,
il ne faudra pas m'en vouloir si mes conseils sont erronés.
Le 10/11/2011 18:25, Une Bévue a écrit :
Les deux doivent aller ensemble, à moins bien sûr que ce soit moi qui
n'aie pas compris le manuel.
C'est en gros ce que je suggérais en citant la doc, et c'est aussi ce
qu'a suggéré SAM.
À 1 ??? Je suppose que tu veux dire « différent de FALSE », ce qui est
quand même différent. Ton message d'erreur parlait de « non-objet », or
d'après la doc on ne peut avoir un non-objet que si la valeur retournée
est FALSE.
Ben c'est qu'est-ce que j'dis !
Le code de retour de... ?
Voilà encore un cas où tu utilises une variable sans savoir si
elle est correcte. D'après la doc, $db ne peut pas valoir FALSE,
mais le new PDO peut lever une exception à gérer avec try-catch
(à moins que ça n'avorte l'exécution si l'exception n'est pas
traitée ?).
Oui, ça me semble bien.
Ah, ok. Il n'empêche que ce serait plus propre si tu le mettais.
D'accord, tiens-nous au courant !
Bon le code (qui marche si je ne provoque pas d'erreur volontairement) :
try {
$db=new PDO("sqlite:../landp.db");
$res=$db->query('SELECT ROWID, * FROM categories');
if($res){
while($row=$res->fetch()){
print_r($row);
echo "<br />";
}
}else{
echo "nPDOStatement::errorCode(): ";
print $res->errorCode();
echo "nPDOStatement::errorInfo():n";
$arr=$res->errorInfo();
print_r($arr);
}
$db=null; // fermeture connexion
} catch (PDOException $e) {
print "Erreur !: " . $e->getMessage() . "<br/>";
die();
}
- 1 - je n'ai jamais de "PDOException" même si le fichier
"../landp.db" n'esxiste pas;
- 2 - si je provoque une erreur en mettant :
$db=new PDO("sqlite:../landp-fichier-inexistant.db");
J'ai le résultat :
PDOStatement::errorCode():
Fatal error: Call to a member function errorCode() on a non-object in
/home/mfj/Sites/landp/php/pdo_cat_test.php on line 33
ce qui est plutôt bidonnant...
notes bien que je n'ai jamais fait de test sur $db puisque dans un try /
catch.
ce qui est plutôt logique !
Enfin, réfléchis : tu ne peux pas appeler $res->fetch() parce que $res
n'est pas un PDOStatement (il vaut FALSE) ; comment dans ce cas peux-tu
imaginer pouvoir appeler $res->errorCode() ? FALSE->errorCode() ???
Ok.
euh, ce n'est pas fetch qui est à false mais $res (càd $db->query(...))
ensuite la doc dit bien :
PDOStatement->errorCode
(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0)
PDOStatement->errorCode — Récupère le SQLSTATE associé lors de la
dernière opération sur la requête
Report a bug
cf.
exemple donné avec prepare mais query est équivalent<:
Exemple #1 Détermine la catégorie de l'erreur qui survient
<?php
/* Provoque une erreur -- la table BONES n'existe pas */
$err = $dbh->prepare('SELECT skull FROM bones');
$err->execute();
echo "nPDOStatement::errorCode(): ";
print $err->errorCode();
?>ut à fait mon cas de figure...
ET, à la page :
Valeurs de retour
PDO::query() retourne un objet PDOStatement, ou FALSE si une erreur
survient.
????
ce qui est to