Gestion des messages d'erreurs PDO

Résolu/Fermé
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 - Modifié par emrh le 17/03/2016 à 08:57
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 - 19 mars 2016 à 08:06
Bonjour à tous,

Je viens de commencer en local une petite webapplication de gestion.
j'utilise PDO et j'aimerai informer proprement et clairement l'utilisateur
du pourquoi du non fonctionnement de telle ou telle action.
En clair, comment récupérer l'erreur générée par PDO et afficher un
message dans les cas suivants entres autres :

- Doublon du nom du fournisseur dans la base,
- Suppression du fournisseur impossible car il possède un lien avec la table
factures (reste une facture attachée à ce fournisseur),
- Vente produit impossible car la quantité vendue est supérieure au stock existant,
- etc...

Et éviter ainsi ce genre de message :

Erreur : SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'SARL MACHIN TRUC' for key 'nom_fournisseur'

J'ai pondu ça qui fonctionne :


if (isset($_GET['id'])) {
$id = $_GET['id'];
try {
$req = "DELETE FROM fournisseurs WHERE id_fournisseur='$id'";
$req = $bdd->query($req);
$message='Le fournisseur a bien été supprimé...';
}
catch (PDOException $e){
$erreur = explode(':', $e->getMessage());
if($erreur[2]==1451){
echo 'Ce fournisseur possède encore des factures dans la base de données, il ne peut etre supprimé !';
}
else {
echo $e -> getMessage();
}
}
}



Ma question est : est-ce propre de coder ainsi ?
Ne peut on pas utiliser plutôt un regexp (que je ne connais que de nom) pour récupérer un '1062' en cas de doublon ou un '1451' en cas de liaison avec une clé étrangère !

Ces codes sont ils stockés quelque part ailleurs que dans $e->getMessage() et donc directement récupérables ?

Merci d'avance pour vos réponses !

2 réponses

jordane45 Messages postés 38136 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 16 avril 2024 4 649
17 mars 2016 à 09:28
Bonjour,



Ces codes sont ils stockés quelque part ailleurs que dans $e->getMessage() et donc directement récupérables ?


Tu peux utiliser getcode :
https://www.php.net/manual/fr/exception.getcode.php


Ma question est : est-ce propre de coder ainsi ?

Oui et non.
Disons qu'un SWITCH serait sûrement mieux qu'un ensemble de IF ELSE...
0
jordane45 Messages postés 38136 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 16 avril 2024 4 649
17 mars 2016 à 09:30
Après... pour gérer les DUPLICATE et autres erreurs de ce genre.... il est préférable je pense de faire une fonction qui ira requêter ( via un SELECT ) ta table et vérifier l'information.... avant de faire tes INSERT ou tes DELETE.
Je trouve ça plus propre que d'utiliser les "erreurs" pdo.
(et puis le jour où tu utilises une BDD sans clé étrangères ou sans KEY UNIQUE..... tu seras bien content d'avoir ce genre de fonctions.... )
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
Modifié par emrh le 19/03/2016 à 08:10
Merci jordane45 pour ta réponse...

getcode me renvoie systématiquement 23000 comme code erreur (en tous cas pour une suppression avec contrainte de clé étrangère ou ajout d'un doublon)...C'est pour ça que j'allais chercher par un explode le 1062 ou 1451 comme info précise dans le message $e->getMessage()...

Tu as raison, le SELECT serait plus judicieux qu'une suite de if qui s'imbriquent ! Merci du tuyau !

Je voulais éviter d'avoir à utiliser du javascript (en cas de désactivation dans le navigateur) mais je me demande si c'est judicieux de laisser l'utilisateur remplir toute une fiche fournisseur pour qu'au moment de l'INSERT ou DELETE il se voit averti que ce qu'il veut faire est impossible !

J'avais pondu un script pour une autre appli qui se connectait à une page verif.php. Dès la perte du focus de l'input on allait vérifier dans la table la
présence ou non d'un doubon...
Je vais le repiquer pour cette appli de gestion !

Merci encore jordane45


Pour ceux que ça intéresse, j'avais fait ça :

aliment_ajout.php

... / ...
<label for="nom">Désignation : </label><input type="text" name="nom" id="nom" size="60" maxlength="60" value="" required /><div id="namebox"> </div>
...
...
</body>
</html>


<script type="text/javascript">
$(function(){ // Cette fonction s’exécute une fois tous les éléments de la page chargés
$("#nom").change(function(){ // cette fonction s’exécute au changement de valeur de l'input
var saisie = $(this).val(); // récupération de la valeur saisie par l'utilisateur
$.post("verifaliment.php", { // On envoie la valeur saisie à la page verif en php
"valeurSaisie" : saisie
})
.done(function(data){ // cette fonction est executée au succès de l'appel ajax
if (data == 1) { // => elle prend en param le contenu de la réponse
document.getElementById("namebox").innerHTML = 'Attention : cet aliment a déjà été créé' ;
}
else if (data == 2) {
document.getElementById("namebox").innerHTML = ' ' ;
}
})
.fail(function(){ // cette fonction est executée en cas d'echec de l'appel
alert('Vérification de saisie impossible actuellement !');
});
});
});
</script>





verifaliment.php

<?php
if (isset($_POST['valeurSaisie'])){
// Connexion à la base de données :
require ('connexion.php');
// Formatage de la saisie utilisateur :
$nom = strtoupper($_POST['valeurSaisie']);
// Requête vérification dans bdd si aliment déjà présent :
$requete = $bdd->prepare('SELECT aliment_id FROM menu_aliments WHERE aliment_nom = :nom LIMIT 1');
$requete->execute(array('nom' => $nom));
$count = $requete->rowCount();

if($count > 0){ // L'aliment existe déjà dans la base
$data = 1;
}
else { // L'aliment n'existe pas
$data = 2;
}

// Fermeture connexion
$requete->closeCursor();
echo $data;
}
?>
0