Gestion des messages d'erreurs PDO [Résolu/Fermé]

Signaler
Messages postés
59
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
8 juin 2020
-
Messages postés
59
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
8 juin 2020
-
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

Messages postés
31597
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
4 mars 2021
3 298
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...
Messages postés
31597
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
4 mars 2021
3 298
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.... )
Messages postés
59
Date d'inscription
mardi 9 décembre 2014
Statut
Membre
Dernière intervention
8 juin 2020

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;
}
?>