Lors de la connexion et de la manipulation de bases de données MySQL à l'aide de PHP, l'extension MySQLI fournit des méthodes riches telles que MySQLI :: Query , MySQLI :: Préparer , etc. Pour exécuter SQL. Cependant, dans le développement réel, en plus de prêter attention à la réussite de SQL, nous devons parfois obtenir le processus d'exécution. Ces avertissements peuvent ne pas faire échouer l'exécution de SQL, mais ils cachent des problèmes potentiels.
La méthode MySQLI :: Get_Warnings de PHP peut obtenir tous les avertissements générés par la dernière opération dans la connexion. Cependant, son utilisation est souvent fragmentée, et si nous pouvons l'envelopper dans un module, il peut être facilement réutilisé dans le projet et garder le code soigné.
Cet article décrira comment encapsuler MySQLI :: Get_Warnings dans un module de capture d'avertissement MySQL réutilisable.
La méthode mysqli :: get_warnings () renvoie une référence à la liste liée des objets mysqli_warning , à travers lesquels toutes les informations d'avertissement sont accessibles. Chaque objet MySQLI_WARNING contient les informations suivantes:
Message : message d'avertissement
SQLSTATE : code d'erreur SQLState
Errno : code d'erreur MySQL
Notre objectif est de mettre en œuvre une classe WarningCollector qui est capable de:
Se lier à une instance mysqli ;
Exécuter des instructions SQL et collecter automatiquement les informations d'avertissement;
Formater les informations d'avertissement et les retourner au journal;
Fournir des méthodes de nettoyage d'avertissement pour éviter les informations d'avertissement restantes pour affecter la prochaine opération.
Ce qui suit est le code d'implémentation complet:
<?php
class WarningCollector
{
private mysqli $conn;
private array $warnings = [];
public function __construct(mysqli $connection)
{
$this->conn = $connection;
}
public function execute(string $sql): bool|mysqli_result
{
$result = $this->conn->query($sql);
$this->collectWarnings();
return $result;
}
private function collectWarnings(): void
{
$this->warnings = []; // Effacer les vieilles données
$warning = $this->conn->get_warnings();
while ($warning) {
$this->warnings[] = [
'errno' => $warning->errno,
'sqlstate' => $warning->sqlstate,
'message' => $warning->message,
];
$warning = $warning->next();
}
}
public function getWarnings(): array
{
return $this->warnings;
}
public function hasWarnings(): bool
{
return !empty($this->warnings);
}
public function logWarnings(string $logPath = '/tmp/mysql_warnings.log'): void
{
if ($this->hasWarnings()) {
foreach ($this->warnings as $w) {
$entry = sprintf(
"[%s] MySQL Warning - Errno: %d, SQLSTATE: %s, Message: %s\n",
date('Y-m-d H:i:s'),
$w['errno'],
$w['sqlstate'],
$w['message']
);
file_put_contents($logPath, $entry, FILE_APPEND);
}
}
}
}
L'utilisation de ce module est très simple. Utilisez-le simplement pour encapsuler la connexion avant d'exécuter SQL:
<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'database');
$collector = new WarningCollector($mysqli);
// mettre en œuvre SQL
$sql = "INSERT INTO demo (name) VALUES ('duplicate-key')";
$collector->execute($sql);
// Vérifier l'avertissement
if ($collector->hasWarnings()) {
$collector->logWarnings();
print_r($collector->getWarnings());
}
Cette encapsulation est particulièrement utile dans les catégories de projets suivantes:
Script de migration des données: l'avertissement peut révéler une troncature du champ ou un décalage de type;
Outil d'importation par lots: les avertissements liés aux contraintes sont facilement déclenchés lors de l'insertion de grands lots de données;
Surveillance de la qualité des données: collecte centralisée des avertissements via le système de journal pour une analyse ultérieure;
Si vous utilisez des frameworks tels que Laravel, Symfony, etc., vous pouvez également les encapsuler en middleware ou des classes de service en fonction de cette idée pour l'injection de dépendance.
MySQLI :: get_warnings () ne peut obtenir des avertissements générés par la dernière opération, alors assurez-vous de les appeler immédiatement après chaque exécution SQL;
Si vous utilisez des instructions préparées , il est recommandé de vous assurer que vous exécutez avant d'obtenir un avertissement;
Différentes versions MySQL ont des niveaux de soutien légèrement différents pour les avertissements, et il est recommandé que les versions de développement et d'environnement de production soient cohérentes;
En encapsulant MySQLI :: Get_Warnings dans les modules, nous captions et gérons non seulement plus facilement les avertissements SQL, mais contribuons également à améliorer la maintenabilité et la robustesse du système. Vous pouvez davantage vous développer en fonction de la structure de votre projet, comme l'ajout de support de canal de journal, le filtrage du niveau d'avertissement, etc.
Pour des exemples de projet complets, veuillez vous référer à:
https://gitbox.net/example/mysql-warning-collector