1- Introduction

Dans ce tutorial, nous allons voir comment compresser ou lister le contenu d'un fichier ZIP. PHP offre deux méthodes pour exploiter les fichiers compressés, l'une en utilisant la bibliothèque "zip.lib.php" l'autre en utilisant l'extension "php_zip". Nous allons voir ces deux méthodes. Pour ce faire nous utiliserons la première pour la compression et la seconde pour la décompression.

Au préalable installez la bibliothèque "zip.lib.php". Téléchargeable ici. Vous pouvez la mettre dans un dossier de votre site, ainsi qu'activer l'extension "php_zip" sur votre serveur (voir site officiel de PHP), si vous êtes hébergé en mutualisé renseignez vous en faisant exécutant la fonction :

<?php
php_info() ;
?>

2- Compresser un ou plusieurs fichiers en ZIP

Le code de base : un seul fichier

Avant toute chose vous devez inclure la librairie :

<?php
require("zip.lib.php") ; //indiquez le chemin d'accès à la librérie
?>

Créer après le fichier Zip. Pour cela, nous allons utiliser la fonction zipfile().

<?php
$zip = new zipfile() ; //on crée un fichier zip
?>

Remarque : la fonction zipfile() n'est pas dans le manuel PHP mais elle est défnie dans la libérie.

Ensuite ouvrir le fichier à zipper (se référer au tutoriel sur les fichiers FTP)

<?php
$filename = 'test.txt' ;
$fp = fopen($filename,'r') ; //on ouvre le fichier en lecture seule
$contenu = fread($fp, filesize($filename)) ; //on enregistre le contenu
fclose($fp) ; //on ferme FTP
?>

Puis on ajoute le fichier text.txt à l'archive. Pour cela on utilise la fonction addfile().

<?php
$zip->addfile($contenu, $filename) ; //on ajoute le fichier
?>

On associe le fichier Zip, on utilise pour ça la simple fonction file().

<?php
$archive = $zip->file() ; //on associe l'archive
?>

On ajoute les en-têtes, fonction header().

<?php
header('Content-Type: application/x-zip') ; //on détermine les en-tête
header('Content-Disposition: inline; filename=archive.zip') ;
?>

Enfin on envoi le tout au navigateur. Fonction echo().

Et voilà ce que cela donne :

<?php
require("zip.lib.php") ; //indiquez le chemin d'accès à la librérie

$zip = new zipfile() ; //on crée un fichier zip

$filename = 'test.txt' ;
$fp = fopen($filename,'r') ; //on ouvre le fichier en lecture seule
$contenu = fread($fp, filesize($filename)) ; //on enregistre le contenu
fclose($fp) ; //on ferme FTP

$zip->addfile($contenu, $filename) ; //on ajoute le fichier

$archive = $zip->file() ; //on associe l'archive

header('Content-Type: application/x-zip') ; //on détermine les en-tête
header('Content-Disposition: inline; filename=archive.zip') ;

echo $archive ;
?>

Avec plusieurs fichiers

Pas tellement plus compliqué ! On ne fait qu'ajouter une boucle avec while et le tour est joué.

On stoque tout les noms de fichiers à ajouter à l'archive dans le tableau filename.

<?php
$filename = array('test1.txt','test2.txt','test3.txt') ;
?>

On crée une boucle

<?php
$a = 0 ;
while(count($filename)>$a)
{
$fp = fopen($filename[$a],'r') ; //on ouvre le fichier en lecture seule
$contenu = fread($fp, filesize($filename[$a])) ; //on enregistre le contenu
fclose($fp) ; //on ferme FTP

$zip->addfile($contenu, $filename[$a]) ; //on ajoute le fichier
$a++; //on incrémente $a
}
?>

Puis tout le reste est le même que pour un seul fichier. On obtient alors :

<?php
require("zip.lib.php") ; //indiquez le chemin d'accès à la librérie

$zip = new zipfile() ; //on crée un fichier zip

$filename = array('test1.txt','test2.txt','test3.txt') ;

$a = 0 ;
while(count($filename)>$a)
{
$fp = fopen($filename[$a],'r') ; //on ouvre le fichier en lecture seule
$contenu = fread($fp, filesize($filename[$a])) ; //on enregistre le contenu
fclose($fp) ; //on ferme FTP

$zip->addfile($contenu, $filename[$a]) ; //on ajoute le fichier
$a++; //on incrémente $a
}

$archive = $zip->file() ; //on associe l'archive

header('Content-Type: application/x-zip') ; //on détermine les en-tête
header('Content-Disposition: inline; filename=archive.zip') ;

echo $archive ;
?>

Remarque : si le chemin d'accès vers un des fichiers inclus dans l'archive est erroné, l'archive contiendra un fichier de son nom mais vide : poids = 0 octets.

3- Lire le contenu d'un fichier ZIP

Pour lister les différents fichiers d'un document ZIP, nous allons utiliser la méthode qui nécessite l'activation de l'extension "php_zip".

Ouvrons le fichier zip :

<?php
$zip = zip_open("/tmp/test.zip");
?>

Attention ! entrer le chemin total !

On vérifie que le fichier est correctement ouvert :

<?php
if ($zip) {
}
?>

On crée une boucle qui tourne jusqu'a épuisement des fichiers :

<?php
while ($zip_entry = zip_read($zip)) {
}
?>

Et enfin on affiche toutes les données relatives au fichier :

<?php
echo "Nom :                    " . zip_entry_name($zip_entry) . "<br>";
echo "Poids actuel : " . zip_entry_filesize($zip_entry) . "<br>";
echo "Poids compressé: " . zip_entry_compressedsize($zip_entry) . "<br>";
echo "Méthode de compression : " . zip_entry_compressionmethod($zip_entry) . "<br>"; ?>

Cela nous donne :

<?php
$zip = zip_open("/tmp/test.zip");
if ($zip) {
     while($zip_entry = zip_read($zip)) {
          echo "Nom :                    " . zip_entry_name($zip_entry) . "<br>";
echo "Poids actuel : " . zip_entry_filesize($zip_entry) . "<br>";
echo "Poids compressé: " . zip_entry_compressedsize($zip_entry) . "<br>";
echo "Méthode de compression : " . zip_entry_compressionmethod($zip_entry) . "<br>"; } } ?>

Tutorial écrit par Micha Mazaheri.