Position actuelle: Accueil> Derniers articles> mysqli_stmt :: préparer les pièges communs dans les transactions

mysqli_stmt :: préparer les pièges communs dans les transactions

gitbox 2025-05-29

Dans PHP, lorsque vous utilisez l'extension MySQLI pour les opérations de base de données, MySQLI_STMT :: Préparer est une méthode clé pour les instructions de prétraitement. Il peut effectivement empêcher l'injection de SQL et améliorer l'efficacité de l'exécution. Cependant, dans le traitement des transactions, lorsque vous utilisez MySQLI_STMT :: Préparez , vous rencontrez souvent certains pièges, ce qui conduit les transactions à ne pas être soumises ou à randonner correctement, et même aux incohérences de données. Cet article analysera ces pièges communs en détail et fournira des solutions correspondantes.

1. La relation de base entre les transactions et les déclarations de prétraitement

La transaction est un ensemble d'opérations dans la gestion des bases de données qui nécessitent que ces opérations réussissent ou que toutes échouent. En utilisant le contrôle de transaction de MySQLI , la méthode suivante est généralement appelée:

 $mysqli->begin_transaction();
$mysqli->commit();
$mysqli->rollback();

MySQLI_STMT :: Préparer des instructions et des précompiles SQL. Il est utilisé correctement pour s'assurer que l'instruction SQL est légale et que les paramètres liés sont corrects.

2. Pièges et solutions courantes

1. Préparer le résultat non vérifié par déclaration de prétraitement

Point de stand : Après avoir appelé $ stmt = $ mysqli-> préparer ($ sql);, il n'est pas vérifié si $ stmt est faux . Si la préparation échoue si les erreurs de syntaxe SQL ou d'autres raisons, la transaction continue de s'exécuter, et les opérations ultérieures peuvent signaler une erreur, ce qui entraîne une exception de transaction.

résoudre :

 $stmt = $mysqli->prepare($sql);
if ($stmt === false) {
    $mysqli->rollback();
    throw new Exception('Prepare failed: ' . $mysqli->error);
}

Dans une transaction, si la préparation échoue, reculez et arrêtez les opérations ultérieures.

2. Préparer a été exécuté avant le début de la transaction

Points : Parfois, le développeur exécutera $ stmt = $ mysqli-> prépare ($ sql); Avant d'appeler $ mysqli-> begin_transaction () ;. Cependant, sous certaines versions ou configurations MySQL, les instructions de prétraitement sont automatiquement engagées implicitement, ce qui entraîne l'effet de transaction invalide.

résoudre :

Assurez-vous d'abord de démarrer la transaction, puis d'exécuter Préparer:

 $mysqli->begin_transaction();
$stmt = $mysqli->prepare($sql);
// Liaison et exécution ultérieures

3. Préparer non séparé lorsque vous utilisez plusieurs instructions SQL

Points : Les instructions de prétraitement ne prennent pas en charge la rédaction de plusieurs instructions SQL à la fois. Si $ SQL contient plusieurs instructions divisées par semi-colons, Préparera.

résoudre :

Assurez-vous de préparer une seule instruction SQL à chaque fois et exécuter plusieurs instructions séparément si nécessaire.

4. Le défaut de lier les paramètres provoque correctement l'exception des données

Point de stand : les erreurs de liaison des paramètres, telles que le type décalage ou tous les espaces réservés non liés, entraîneront une défaillance de l'exécution et la transaction finira par échouer.

résoudre :

Assurez-vous de vous assurer que le type et le nombre de paramètres liés sont corrects, tels que:

 $stmt->bind_param('si', $name, $id);

Et vérifiez la valeur de retour de bind_param .

5. J'ai oublié de fermer la déclaration de prétraitement

Point de stand : si $ stmt-> close () n'est pas appelé avant la fin de la transaction, cela peut entraîner la libération de la ressource de connexion, affectant les opérations de transaction ultérieures.

résoudre :

Avant la fin de la transaction, appelez $ stmt-> close () pour vous assurer que la ressource est publiée dans le temps.

6. Ignorer la gestion des erreurs et la capture des exceptions

Point de stand : exception ou erreur non revêtue, ce qui a permis que la transaction ne soit pas correctement engagée ou renvoyée.

résoudre :

À l'aide de la structure de couple d'essai, faites rouler les transactions lors de la capture d'exceptions:

 try {
    $mysqli->begin_transaction();

    $stmt = $mysqli->prepare($sql);
    if ($stmt === false) {
        throw new Exception($mysqli->error);
    }

    $stmt->bind_param('si', $name, $id);
    $stmt->execute();

    $mysqli->commit();
} catch (Exception $e) {
    $mysqli->rollback();
    echo "Transaction failed: " . $e->getMessage();
}

3. Exemple complet

 <?php
$mysqli = new mysqli('gitbox.net', 'user', 'password', 'database');
if ($mysqli->connect_error) {
    die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}

try {
    $mysqli->begin_transaction();

    $sql = "UPDATE users SET name = ? WHERE id = ?";
    $stmt = $mysqli->prepare($sql);
    if ($stmt === false) {
        throw new Exception('Prepare failed: ' . $mysqli->error);
    }

    $name = 'Alice';
    $id = 123;
    if (!$stmt->bind_param('si', $name, $id)) {
        throw new Exception('Bind param failed: ' . $stmt->error);
    }

    if (!$stmt->execute()) {
        throw new Exception('Execute failed: ' . $stmt->error);
    }

    $stmt->close();

    $mysqli->commit();
    echo "Transaction succeeded.";
} catch (Exception $e) {
    $mysqli->rollback();
    echo "Transaction failed: " . $e->getMessage();
}

$mysqli->close();
?>

4. Résumé

  • Exécutez toujours Préparez après le démarrage de la transaction.

  • Vérifiez les valeurs de retour de préparation , bind_param et exécuter .

  • Chaque préparation ne traite qu'une seule déclaration.

  • Assurez-vous de faire reculer la transaction lorsqu'une exception se produit.

  • Fermez la ressource de déclaration de prétraitement.

Suivre les spécifications ci-dessus peut éviter efficacement les pièges courants rencontrés dans l'utilisation de MySQLI_STMT :: Préparer dans le traitement des transactions, d'assurer la cohérence des données et la robustesse du code.