Lors du fonctionnement des fichiers ZIP dans PHP, les fonctions couramment utilisées incluent zip_open () et zip_read () . Ces deux fonctions peuvent être utilisées en combinaison pour ouvrir un fichier zip et lire les entrées dedans une par une. Cependant, les développeurs rencontrent souvent un problème: pendant le processus d'appel zip_read () pour lire une entrée, le programme peut tomber dans une boucle infinie, entraînant une utilisation excessive des ressources et même écraser le programme.
Cet article se concentrera sur l'explication des causes communes des boucles infinies dans zip_read () et fournira des méthodes de prévention efficaces.
Lorsque zip_read () lit les entrées dans un fichier zip, itère via des pointeurs internes. Si le fichier zip lui-même est corrompu ou si la condition pour terminer la lecture n'est pas appelée correctement, elle entraînera zip_read () pour renvoyer à plusieurs reprises le même élément, ce qui entraîne une boucle morte.
Les raisons courantes comprennent:
Le fichier zip est corrompu ou a un format anormal , ce qui ne provoque pas de déplacement correctement le pointeur d'entrée.
Les erreurs de jugement de la condition circulaire , telles qu'aucun jugement ne parviennent à la fin du fichier zip.
La ressource zip n'est pas fermée correctement ou le pointeur n'est pas déplacé .
L'exemple suivant montre comment utiliser en toute sécurité zip_read () pour traverser les entrées dans un fichier zip et empêcher les boucles infinies:
<?php
$zipFile = 'http://m66.net/sample.zip';
// Ouvrir ZIP document
$zip = zip_open($zipFile);
if (!is_resource($zip)) {
echo "无法Ouvrir ZIP document";
exit;
}
while (($zipEntry = zip_read($zip)) !== false) {
$entryName = zip_entry_name($zipEntry);
// Traitement des entrées
echo "读取document条目:$entryName\n";
// Ouvrir条目
if (zip_entry_open($zip, $zipEntry)) {
$contents = zip_entry_read($zipEntry, zip_entry_filesize($zipEntry));
// Traitement du contenu,Par exemple, enregistrer ou afficher
zip_entry_close($zipEntry);
}
// Avis:zip_read() Passez automatiquement à l'entrée suivante
}
// fermeture ZIP ressource
zip_close($zip);
?>
Points clés:
Lorsque vous utilisez une boucle zip_read () , vous devez vous assurer que la condition est ! == FALSE pour empêcher la lecture des entrées non valides.
Après avoir utilisé l'entrée, vous devez appeler zip_entry_close () pour fermer l'entrée actuelle pour éviter la fuite des ressources.
Une fois la boucle terminée, appelez zip_close () pour fermer la ressource de fichier zip.
Assurez-vous l'intégrité et le format correct du fichier zip.
Vérifiez si le fichier zip est valide
Avant d'ouvrir un fichier, vous pouvez d'abord vérifier si le fichier existe et est de taille raisonnable pour éviter d'ouvrir un fichier vide ou de corrompre le fichier.
Limiter le nombre de cycles
Si vous rencontrez un fichier incertain, vous pouvez empêcher une boucle morte en définissant le nombre maximum de boucles. Par exemple:
$maxEntries = 1000; // Nombre maximum d'entrées de lecture
$count = 0;
while (($zipEntry = zip_read($zip)) !== false && $count < $maxEntries) {
// Code de traitement
$count++;
}
if ($count >= $maxEntries) {
echo "avertir:La limite d'entrée maximale est atteinte,可能存在异常document。\n";
}
Utilisez d'autres extensions PHP pour remplacer
PHP a également une classe Ziparchive pour faire fonctionner des fichiers ZIP, qui sont plus puissants et plus sûrs. Si vous rencontrez un instable zip_read () , il est recommandé d'utiliser Ziparchive .
<?php
$zip = new ZipArchive();
$zipFile = 'http://m66.net/sample.zip';
if ($zip->open($zipFile) === true) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$entryName = $zip->getNameIndex($i);
echo "读取document条目:$entryName\n";
$stream = $zip->getStream($entryName);
if ($stream) {
$contents = stream_get_contents($stream);
fclose($stream);
// Traitement du contenu
}
}
$zip->close();
} else {
echo "无法Ouvrir ZIP document";
}
?>
Ziparchive n'aura pas de problèmes de boucle infinie lors du traitement, et il est plus flexible.
Lorsque vous utilisez zip_read () , assurez-vous de déterminer si la valeur de retour est fausse pour empêcher une boucle morte.
Assurez-vous que chaque ressource d'entrée et de fichier zip est fermée correctement.
Vous pouvez définir la limite supérieure du nombre d'entrées de boucle pour empêcher les fichiers d'exception de provoquer des boucles infinies.
Il est recommandé d'utiliser la classe ziparchive la plus moderne au lieu de zip_read () .
Grâce à ces méthodes, le problème du PHP tombant dans des boucles infinies lors de l'utilisation de zip_read () peut être évité efficacement, garantissant que le programme s'exécute de manière stable et efficace.