Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

PDO et erreur

15 réponses
Avatar
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)

5 réponses

1 2
Avatar
Antoine Polatouche
Le 11/11/2011 11:10, Une Bévue a écrit :
On 11/11/2011 08:10, Olivier Miakinen wrote:
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() ???



euh, ce n'est pas fetch qui est à false mais $res (càd $db->query(...))



Essaye de comprendre ce qu'Olivier te dit !!!

$res = FALSE

Tu appelles FALSE->errorCode()

PDO n'a rien à voir dans l'histoire.

FALSE->nimportequoi() te donnera toujours
Fatal error: Call to a member function nimportequoi() on a non-object

Erreur que tu peux intercepter dans une exception, mais pas dans une
PDOException.
Avatar
Une Bévue
Le 11/11/2011 15:10, Antoine Polatouche a écrit :
Essaye de comprendre ce qu'Olivier te dit !!!

$res = FALSE

Tu appelles FALSE->errorCode()

PDO n'a rien à voir dans l'histoire.

FALSE->nimportequoi() te donnera toujours
Fatal error: Call to a member function nimportequoi() on a non-object

Erreur que tu peux intercepter dans une exception, mais pas dans une
PDOException.



non, j'ai très bien compris ce que dit Olivier et ce que dit la doc, si :
$res=$db-query(...)

est à false, preuve qu'il y a une erreur, je ne peux pas récupérer le
code de l'erreur.

MAIS la docum que j'ai cité dit le contraire, enfin ne dit pas ça, dit
en tk qu'on peut trécupérer l'erreur.

je souhaitais récupérer le code d'erreur, je vois que ce n'est pas
possible...

D'ailleurs je me suis aperçu hier soir que ce script fonctionnait
différemment sur deux xubuntu 11.10, je dois investiguer à ce sujet.
Pour l'un pas d'erreur quand je tente de me connecter à une base sqlite
qui n'existe pas, la fichier de la base est créé, pour l'autre j'ai le
message d'erreur qui est retourné.
Avatar
Antoine Polatouche
Le 12/11/2011 07:51, Une Bévue a écrit :


non, j'ai très bien compris ce que dit Olivier et ce que dit la doc, si :
$res=$db-query(...)

est à false, preuve qu'il y a une erreur, je ne peux pas récupérer le
code de l'erreur.

MAIS la docum que j'ai cité dit le contraire, enfin ne dit pas ça, dit
en tk qu'on peut trécupérer l'erreur.



La doc que tu cites dit comment récupérer le statut d'une connexion de
base de donnée, ton problème est que tu n'as pas de connexion !



je souhaitais récupérer le code d'erreur, je vois que ce n'est pas
possible...



Est-ce que tu as essayé de mettre $db = new PDO(...) dans un bloc
d'exception ?


D'ailleurs je me suis aperçu hier soir que ce script fonctionnait
différemment sur deux xubuntu 11.10, je dois investiguer à ce sujet.
Pour l'un pas d'erreur quand je tente de me connecter à une base sqlite
qui n'existe pas, la fichier de la base est créé, pour l'autre j'ai le
message d'erreur qui est retourné.



Quel message d'erreur ?

(problème de droits d'écriture de www-data ?)
Avatar
Une Bévue
Le 12/11/2011 19:12, Antoine Polatouche a écrit :
Quel message d'erreur ?



SQLSTATE[HY000] [14] unable to open database file

quand le fichier base de données n'existe pas.


Bon, j'ai trouvé ce qu'il faut faire :

try {
$db=new PDO("sqlite:landp.db"); // 1
$res=$db->query('SELECT ROWID, * FROM kategories'); // 2
if($res){
while($row=$res->fetch()){
print_r($row);
}
}else{
echo "nPDOStatement::errorCode(): ";
print $db->errorCode();
echo "nPDOStatement::errorInfo():n";
$arr=$db->errorInfo();
print_r($arr);
}
echo $html;
$db=null; // fermeture connexion
} catch (PDOException $e) {
print "Erreur !: " . $e->getMessage() . "<br/>";
die();
}
?>
si en "// 1" j'ai une erreur, le fichier n'existe pas, je récupère bien
l'erreur qu niveau du catch, testé sur un ordi seulement.

si en "// 2", comme ici, j'ai une autre erreur, la table kategories
n'existe pas je récupère l'erreur dans le else.

C'est l'exemple donné à la page :
<http://fr2.php.net/manual/fr/pdostatement.errorcode.php>
qui est inexact.

au lieu de :
$err = $dbh->prepare('SELECT skull FROM bones');
$err->execute();

echo "nPDOStatement::errorCode(): ";
print $err->errorCode();

il faut écrire à la dernière ligne :
print $dbh->errorCode();
______^^^^_____________
puisque, comme l'a vu Olivier $err est à false, on ne peut rien en
sortir d'autre.
Avatar
Antoine Polatouche
Le 13/11/2011 07:37, Une Bévue a écrit :

C'est l'exemple donné à la page :
<http://fr2.php.net/manual/fr/pdostatement.errorcode.php>
qui est inexact.

au lieu de :
$err = $dbh->prepare('SELECT skull FROM bones');
$err->execute();

echo "nPDOStatement::errorCode(): ";
print $err->errorCode();

il faut écrire à la dernière ligne :
print $dbh->errorCode();
______^^^^_____________
puisque, comme l'a vu Olivier $err est à false, on ne peut rien en
sortir d'autre.



L'exemple est bon, et dans ce cas $err ne va pas être à false:

$err = $dbh->prepare('SELECT skull FROM bones');
retourne un objet PDOStatement valide, pour peu que $dbh soit valide (ce
qui doit être vérifié avant!)

$err->execute();
retourne false car la table n'existe pas, mais $err est toujours valide
et $err->errorCode() retourne le code d'erreur.

C'est sans doute le nom de la variable qui te trompe:

$statement = $dbh->prepare('SELECT skull FROM bones');
if(! $statement->execute() )
{
echo "nPDOStatement::errorCode(): ";
print $statement->errorCode();
}

La différence entre prepare et query, c'est que prepare ne va pas
retourner false car elle ne teste pas la validité de la requête, donc
l'objet PDOStatement va être valide.
1 2