web-dev-qa-db-fra.com

Questions d'exception sur les AOP - Comment les attraper

J'utilise PDO pour réécrire une interface de site Web pour une base de données. J'avais l'habitude d'utiliser l'extension mysql, mais je n'avais jamais pris la peine de gérer les erreurs, et les quelques gestionnaires d'erreurs que j'avais étaient essentiellement du copier-coller.

Maintenant, j'aimerais bien faire ça. Cependant, j'ai des problèmes pour attraper les erreurs comme je le voudrais (erreurs comme "Entrée en double", "Valeur nulle", etc. dans MySQL). Quelle partie de mon relevé doit être dans le bloc try? Tout devrait-il être là-dedans? J'utilise une Include() pour me connecter à ma base de données (qui a sa propre gestion des erreurs), donc c'est seulement l'exécution de la requête qui a des erreurs dans ce code. Je ne peux pas comprendre pourquoi il ne détecte pas d'erreur lors de l'exécution du code suivant:

try {
  $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer)    VALUES (NULL, :name, :password, :question, :answer)");
  $stmt->bindValue(":name", $_POST['name']);
  $stmt->bindValue(":password", $_POST['password']);
  $stmt->bindValue(":question", $_POST['question']);
  $stmt->bindValue(":answer", $_POST['answer']);
  $stmt->execute();
  echo "Successfully added the new user " . $_POST['name'];
} catch (PDOException $e) {
  echo "The user could not be added.<br>".$e->getMessage();
}

Donc, mes questions: tout cela doit-il être dans le bloc d'essai? Puis-je simplement mettre l'exécution dans le bloc try? Il devrait intercepter l'erreur Duplicate value "John" in key "name", mais passe à la place avec le message de réussite. (Lorsque vous essayez d'ajouter deux utilisateurs "John"). J'ai vérifié dans PHPMyAdmin; l'index est unique et renvoie l'erreur comme prévu, mais n'utilise pas ce code.

19
StuckAtWork

Vous devriez regarder la documentation. Mais si vous ne trouvez rien, vous pouvez ajouter une autre capture:

<?php
try {
  $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer)    VALUES (NULL, :name, :password, :question, :answer)");
  $stmt->bindValue(":name", $_POST['name']);
  $stmt->bindValue(":password", $_POST['password']);
  $stmt->bindValue(":question", $_POST['question']);
  $stmt->bindValue(":answer", $_POST['answer']);
  $stmt->execute();
  echo "Successfully added the new user " . $_POST['name'];
} catch (PDOException $e) {
  echo "DataBase Error: The user could not be added.<br>".$e->getMessage();
} catch (Exception $e) {
  echo "General Error: The user could not be added.<br>".$e->getMessage();
}
?>

Cela doit fonctionner car toutes les exceptions de PHP plugins héritent de la classe native Exception PHP. (Depuis 5.0 si ma mémoire est bonne).

15
niconoe

Questions d'exception sur les AOP - Comment les attraper

Comme règle -

NE PAS les attraper .

Par exemple, votre code ici devrait être écrit de cette façon

$stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)");
$stmt->bindValue(":name", $_POST['name']);
$stmt->bindValue(":password", $_POST['password']);
$stmt->bindValue(":question", $_POST['question']);
$stmt->bindValue(":answer", $_POST['answer']);
$stmt->execute();
echo "Successfully added the new user " . $_POST['name'];

sans essayer ni intercepter les appels. Parce que vous n'avez pas de scénario particulier pour gérer une exception ici (un écho simple ne compte guère comme un scénario de gestion).

Au lieu de cela, laissez-le bouillonner jusqu'au gestionnaire d'erreurs à l'échelle de l'application (ne soyez pas effrayé par le terme, PHP en a déjà un intégré).

Cependant, j'ai des problèmes pour attraper les erreurs comme je le voudrais (erreurs comme "Entrée en double", "Valeur nulle", etc. dans MySQL).

Seulement dans le cas où si vous avez un certain scénario , vous devez utiliser l'opérateur try-catch, mais vous devez toujours vérifier si l'erreur que vous avez obtenu est celui que vous attendiez. Sinon, une exception doit être levée:

try {
    $pdo->prepare("INSERT INTO users VALUES (NULL,?,?,?,?)")->execute($data);
} catch (PDOException $e) {
    if ($e->getCode() == 1062) {
        // Take some action if there is a key constraint violation, i.e. duplicate name
    } else {
        throw $e;
    }
}

et bien sûr (comme cela s'est avéré être le véritable problème pour cette question), vous devez configurer PDO en mode exception, soit dans un paramètre constructeur de simplement en ajoutant le code

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

juste après la connexion.

10