Dans la programmation PHP, l'extension MySQLI est utilisée pour interagir avec la base de données MySQL, et MySQLI_STMT en est un composant important, souvent utilisé pour exécuter des instructions de prétraitement. MySQLI_STMT :: $ ERROR est une propriété dans l'objet MySQLI_STMT qui renvoie le message d'erreur qui se produit lors de l'exécution des instructions SQL. Si l'exécution de SQL est réussie, $ Error sera vide. Si une erreur se produit, elle contiendra des informations d'erreur détaillées pour faciliter le développeur pour résoudre les problèmes.
Cependant, lors de l'utilisation de l'erreur MySQLI_STMT :: $ dans les transactions, les développeurs peuvent rencontrer des pièges. Cet article discutera de ces problèmes communs et donnera des solutions à la façon de les éviter.
Dans les transactions, MySQLI fournit des méthodes telles que begin_transaction () , commit () et rollback () pour gérer les transactions de base de données. Si une erreur se produit lors de l'exécution de la transaction, vous devez vous assurer de faire reculer la transaction à l'aide de Rollback () pour éviter l'incohérence des données. Cependant, si vous ne comptez que sur MySQLI_STMT :: $ Erreur pour déterminer si la transaction est réussie, certaines erreurs peuvent être manquées, ce qui a permis à la transaction de retourner.
Utilisez MySQLI :: Errno pour vérifier si une erreur se produit et remontez toujours la transaction lorsqu'une erreur se produit. Cela garantit que peu importe où les erreurs se produisent, elles peuvent être manipulées à temps.
$mysqli->begin_transaction();
$stmt = $mysqli->prepare("INSERT INTO users (username, email) VALUES (?, ?)");
$stmt->bind_param("ss", $username, $email);
if (!$stmt->execute()) {
echo "Error executing query: " . $stmt->error;
$mysqli->rollback(); // Si une erreur se produit,Transactions en arrière
exit();
}
// Si tout va bien,Soumettre les transactions
$mysqli->commit();
MySQLI_STMT :: $ Erreur ne renvoie que les informations d'erreur pour une seule exécution de déclaration, elle ne couvre pas les erreurs de l'ensemble de la transaction. Si vous exécutez plusieurs instructions et comptez uniquement sur $ STMT-> Erreur pour vérifier les erreurs, vous pouvez manquer l'erreur globale de la transaction, ce qui entraîne une incohérence des données.
MySQLI permet d'exécuter des transactions dans plusieurs connexions de base de données. Lorsqu'un développeur exécute une transaction, il peut démarrer par erreur une transaction sur une connexion et exécuter une requête sur une autre connexion, provoquant un chaos de gestion des transactions. Lorsque l'erreur MySQLI_STMT :: $ est appelée, si une erreur se produit sur l'opération effectuée sur différentes connexions, l'erreur peut ne pas être capturée dans le temps, ce qui entraîne un état incohérent de l'application.
Assurez-vous toujours que toutes les opérations de la transaction sont effectuées sur la même connexion de la base de données. Vous pouvez utiliser la connexion MySQLI Object pour vous assurer que le contexte de l'ensemble de la transaction est exécuté sous la même connexion.
$mysqli->begin_transaction(); // Assurez-vous que toutes les transactions sont effectuées sur la même connexion
$stmt1 = $mysqli->prepare("INSERT INTO users (username, email) VALUES (?, ?)");
$stmt1->bind_param("ss", $username, $email);
$stmt2 = $mysqli->prepare("INSERT INTO orders (user_id, amount) VALUES (?, ?)");
$stmt2->bind_param("id", $user_id, $amount);
// Effectuer une action
if (!$stmt1->execute() || !$stmt2->execute()) {
echo "Error executing queries: " . $mysqli->error;
$mysqli->rollback();
exit();
}
$mysqli->commit(); // Assurez-vous de soumettre
Cela garantit que toutes les opérations de la base de données sont effectuées sous la même connexion, en évitant la confusion de la gestion des transactions croisées.
Dans MySQL, les niveaux d'erreur des transactions sont divisés en différents types. Certaines erreurs peuvent être fatales et nécessiter un recul immédiat des transactions; tandis que d'autres peuvent être des niveaux d'avertissement qui vous permettent de continuer à exécuter. MySQLI_STMT :: $ L'erreur ne renverra que les messages d'erreur SQL, mais ne vous dira pas la gravité de l'erreur.
Dans une transaction, vérifiez d'abord si MySQLI_STMT :: $ L'erreur est vide, puis prenez les mesures appropriées en fonction du type d'erreur. S'il s'agit d'une erreur fatale, la transaction doit être annulée; S'il s'agit d'une erreur d'avertissement, vous pouvez choisir de continuer.
if (!$stmt1->execute()) {
if ($stmt1->errno) {
echo "Fatal error: " . $stmt1->error;
$mysqli->rollback(); // 致命错误时Transactions en arrière
exit();
} else {
echo "Warning: " . $stmt1->error;
// Vous pouvez choisir de continuer à effectuer d'autres opérations
}
}
Bien que les instructions de prétraitement de MySQLI aient contribué à prévenir les attaques d'injection SQL, si les développeurs n'utilisent pas correctement la méthode bind_param () , l'application sera exposée au risque d'attaques d'injection SQL. Même si vous utilisez MySQLI_STMT :: $ Erreur dans votre transaction pour attraper des erreurs, si l'injection SQL est autorisée, ces messages d'erreur peuvent être exposés à l'attaquant.
Utilisez toujours les méthodes bind_param () ou bind_value () pour lier les paramètres pour vous assurer que le type de données du paramètre est correctement défini.
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username); // Lier les paramètres du nom d'utilisateur,prévenir SQL injection
$stmt->execute();
De cette façon, même si certaines erreurs sont capturées, la structure ou les informations sensibles de la base de données ne seront pas exposées à l'attaquant.
Lorsque vous utilisez l'erreur MySQLI_STMT :: $ , les développeurs doivent faire attention à gérer les erreurs dans les transactions pour éviter les omissions qui conduisent à l'incohérence des données. Les pièges les plus courants comprennent: les transactions ne reculent pas correctement, les gâchis de gestion des transactions sous différentes connexions, ignorant les niveaux d'erreur de base de données et empêchant à tort l'injection SQL. Ces problèmes peuvent être considérablement réduits grâce à une gestion des erreurs raisonnable, en veillant à ce que les transactions soient exécutées sous la même connexion et l'utilisation raisonnable de bind_param () .