PHP MySQL pour PDO code de Transaction de la structure
Je suis en train de créer ma première transaction MySQL à l'aide de PHP/PDO...
J'ai juste une petite question, quelle est la meilleure façon de déterminer si la requête précédente a été un succès ou pas? Voici ce que j'ai en ce moment, mais j'aimerais trouver un moyen de tester la requête avec une instruction if.
C'est assez bien se moquer de code pour essayer d'obtenir un modèle de travail.. je sais que $résultats n'est pas efficace de tester si quelque chose est bon ou mauvais.. je l'ai, il y a plus d'un titulaire de place pour la vraie affaire quand vient le temps..
if ($_POST['groupID'] && is_numeric($_POST['groupID'])) {
$sql = "SET AUTOCOMMIT=0";
$dbs = $dbo->prepare($sql);
$dbs->execute();
$sql = "START TRANSACTION";
$dbs = $dbo->prepare($sql);
$dbs->execute();
$sql = "DELETE FROM users_priveleges WHERE GroupID=:groupID";
$dbs = $dbo->prepare($sql);
$dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$dbs->execute();
try {
$sql = "DELETE FROM groups WHERE GroupID=:groupID LIMIT 1";
$dbs = $dbo->prepare($sql);
$dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$dbs->execute();
$results["error"] = null;
$results["success"] = true;
try {
$sql = "DELETE FROM users WHERE Group=:groupID";
$dbs = $dbo->prepare($sql);
$dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$dbs->execute();
$results["error"] = null;
$results["success"] = true;
$sql = "COMMIT";
$dbs = $dbo->prepare($sql);
$dbs->execute();
}
catch (PDOException $e) {
$sql = "ROLLBACK";
$dbs = $dbo->prepare($sql);
$dbs->execute();
$results["error"] = "Could not delete associated users! $e";
$results["success"] = false;
}
}
catch (PDOException $e)
{
$sql = "ROLLBACK";
$dbs = $dbo->prepare($sql);
$dbs->execute();
$results["error"] = "COULD NOT REMOVE GROUP! $e";
$results["success"] = false;
}
}
- Pourquoi ne pas utiliser PDO est beginTransaction(), commit() et rollback() méthodes?
- LOL je viens d'apprendre de la beginTransaction méthode ce matin... j'ai pensé que les deux autres étaient là, mais n'avais pas regardé en eux encore. C'est sur la TODO liste tho merci!
- Aussi, vous n'avez pas à préparer() à chaque déclaration, en fait, c'est plutôt inutile pour ceux en qui vous n'allez pas à insérer toutes les variables. Il suffit d'exécuter ceux avec query() à la place. Permet d'économiser sur les deux lignes de code inutiles et se prépare.
Vous devez vous connecter pour publier un commentaire.
Quelques remarques générales:
N'utilisez pas de
bindParam()
sauf si vous utilisez une procédure qui modifie la valeur du paramètrePar conséquent,
use bindValue()
. bindParam() accepte l'argument de la valeur en tant que variable en question. Cela signifie que vous ne pouvez pas faire$stmt->bindParam(':num', 1, PDO::PARAM_INT);
- il génère une erreur.Aussi, PDO a ses propres fonctions pour le contrôle des opérations, vous n'avez pas besoin d'exécuter des requêtes manuellement.
J'ai réécrit votre code légèrement afin de jeter une certaine lumière sur la façon dont AOP peut être utilisé:
GROUP
est un mot réservé SQL, donc vous pouvez avoir besoin de le mettre à l'arrière-citations. Mais il serait préférable de le renommer, de sorte qu'il n'est pas un mot réservé, et aussi pour tous vos tables de nom ilGroupID
de manière cohérente.Je ne prépare pas & exécuter les instructions de la transaction. Je voudrais utiliser PDO::beginTransaction() , PDO::commit(), et PDO::rollback().
PDO::prepare() et PDO::execute() retourne FALSE si il y a une erreur, ou alors ils jettent PDOException si vous setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION).
Dans votre gestionnaire d'exception, vous devriez vérifier PDO::errorInfo() et rapport à la nature de l'erreur. La meilleure pratique est de connecter les premières erreur d'info, mais de donner à l'utilisateur une plus sympathique message.
Ne pas l'écho du sens littéral du message d'erreur dans l'INTERFACE utilisateur -- cela peut donner à l'utilisateur une connaissance inadéquate à propos de votre requête SQL et le schéma.
AOP de la Déclaration
execute()
retourne TRUE en cas de succès et FALSE en cas d'échec, de sorte que vous pouvez tester la valeur de retour de la précédenteexecute()
dans votre instruction if.Cela dit, comme @Bill Kerwin correctement le signale dans sa réponse que je suis totalement upvoting parce que c'est tout à fait correct), il serait préférable d'utiliser
PDO::beginTransaction()
,PDO::commit()
, etPDO::rollback()
.$dbs->errorInfo()
Voir la documentation de php.net/manual/en/pdostatement.errorinfo.php pour une explication de sa valeur de retour.