ZipArchive : Proposez des téléchargements sur votre site
Proposez des téléchargements sur votre site internet grâce à la librairie ZipArchive de PHP.
Les archives Zip sont très utiles pour transmettre un ensemble de fichiers et de dossiers par le biais d’internet. Nous allons étudier dans ce chapitre une façon simple de générer des archives Zip à la volée, à l’aide de la librairie ZipArchive de PHP. Cette application vous sera utile si vous êtes amené à proposer des téléchargements sur votre site internet. Par exemple, l’utilisateur pourra ainsi remplir un « panier » de fichiers qu’il téléchargera en une fois. De même, nous allons aborder les façons de décompresser une archive Zip et récupérer les fichiers qu’elle contient. Vous avez déjà dû utiliser une procédure similaire lors de l’installation de plugins ou de thèmes sur certains CMS tels que WordPress ou Prestashop.
01 – Prérequis
Ce chapitre nécessite la librairie ZipArchive. Vous pouvez vérifier si votre système est compatible avec un simple test. Insérez le code suivant dans un fichier PHP vierge et exécutez-le sur votre serveur :
if (class_exists("ZipArhive")) {
echo "Système OK !";
} else {
echo "Vous devez installer ZipArchive.";
}
Si en retour vous obtenez « Système OK ! », cela signifie que votre système contient la librairie ZipArchive. Sinon, vous pouvez soit l’installer, soit vous renseigner auprès de votre hébergeur.
02 – Création de l’instance
Nous allons tout d’abord initialiser la classe ZipArchive en créant une instance qui va nous permettre d’interagir avec une ou plusieurs archives, qu’elles soient à compresser ou à décompresser. Pour cela, insérez dans un fichier PHP vide les lignes suivantes :
$zip = new ZipArchive;
Nous allons donc à présent travailler uniquement avec l’instance déclarée dans la variable $zip.
03 – Décompression d’une archive 1/2
Nous devons tout d’abord ouvrir l’archive que nous souhaitons extraire. Pour cela, nous utilisons la méthode open().
Afin d’éviter de recevoir une erreur en retour (pour une archive corrompure, inexistante ou inaccessible), nous plaçons l’appel de open() dans une conditon. Nous savons que cette fonction retourne true si l’archive s’est correctement ouverte et false dans les autres cas :
if ($zip->open("archive.zip") === true) {
// Le code des étapes suivantes sera à placer ici.
} else {
die("L'archive n'a pu être ouverte.");
}
04 – Décompression d’une archive 2/2
Nous cherchons à extraire les fichiers contenus dans l’archive ouverte ci-dessus dans un dossier du serveur. Pour la démonstration, nous allons utiliser le dossier « /extraction » se trouvant dans le même répertoire que le fichier. Ce répertoire doit bien sûr être existant sur le serveur et le script doit pouvoir y accéder en écriture. Nous allons à présent utiliser la méthode extractTo() qui va extraire les fichiers contenus dans l’archive dans le dossier de destination. Pour cela, nous ajoutons ce code à la suite :
$zip = extractTo(realpath("extraction"));
Les fichiers de l’archive sont à présent dans le dossier susmentionné. Vous pouvez les traiter dans la suite de votre script.
05 – Ajout de fichiers dans une archive 1/3
Après avoir vu la méthode pour décompresser une archive, nous allons maintenant voir celle qui permet d’en créer une nouvelle. Avant d’ajouter des fichiers dans une archive, nous devons bien évidemment l’ouvrir (ou la créer, le cas échéant). Dès lors, dans un fichier PHP vide, insérez :
if ($zip->open("archive.zip") === true) {
// Le code des étapes suivantes sera à placer ici.
} else {
die("L'archive n'a pu être ouverte.");
}
06 – Ajout de fichiers dans une archive 2/3
Si toutefois nous voulons travailler avec une archive inexistante (dans le cas de la création d’un téléchargement à la volée par exemple), nous devons indiquer à la méthode open() de créer l’archive. Pour cela, nous utilisons le flag de ZipArchive::CREATE, ce qui nous donne le code suivant à la place de celui vu précedemment :
if ($zip->open("nouvelle_archive.zip", ZipArchive::CREATE) === true) {
// Le code des étapes suivantes sera à placer ici.
} else {
die("L'archive n'a pu être ouverte.");
}
07 – Ajout de fichiers dans une archive 3/3
pour ajouter des fichiers dans une archive, qu’elle soit nouvellement créée ou existante, nous allons utiliser la fonction addFile(). Nous l’appellerons autant de fois que nous avons de fichiers à insérer. Cette fonction va également recréer l’arborescence à l’intérieur de l’archive. Par exemple, nous voulons stocker trois fichiers : readme.txt, demo/index.html et demo/index.jpg. Pour cela, nous utiliserons le code suivant :
$zip->addFile("readme.txt");
$zip->addFile("demo/index.html");
$zip->addFile("demo/index.jpg");
La fonction peut utiliser deux arguments. Le premier correspond au chemin réel du fichier tel qu’il est sur le serveur tandis que le second indique l’endroit où il sera placé au sein de l’archive. Cela nous permettra de renommer certain fichier si nécessaire :
$zip->addFile("endymis.txt", "petitdev.txt");
08 – Personnaliser et ajouter un fichier
Pour ajouter des fichiers, nous pouvons utiliser une méthode alternative procédant à partir d’une chaîne de caractères. Cette méthode peut être intéressante lorsque le fichier doit être personnalisé avant son insertion dans l’archive. Prenons un exemple concret. Vous souhaitez inclure un fichier de remerciements personnalisés pour l’utilisateur avec son nom et son prénom. Vous pouvez alors utiliser un code similaire à celui-ci :
$prenom = "Nicolas";
$nom = "Jacob";
$contenu = "Merci $prenom $nom d'avoir téléchargé notre si beau fichier !";
$zip->addFormString("thankyou.txt", $contenu);
Le fichier « thankyou.txt » contenu dans l’archive contiendra alors la chaîne :
Merci Nicolas Jacob d’avoir téléchargé notre si beau fichier !
09 – Compresser un répertoire à la volée 1/3
Cette librairie est très utile mais, dans la plupart des cas, vous serez amené à devoir traiter des dossiers complets. Nous allons voir ici comment compresser un dossier à la volée. Nous allons étendre la classe ZipArchive et créer une fonction récursive (vous trouverez un tutoriel sur la récursivité avec PHP en cliquant ici) qui parcourra les différents répertoires et ajoutera les fichiers dans l’archive. Pour cela, nous créons la structure suivante dans un fichier vide :
class ZipRecursif extends ZipArchive {
public function addDirectory($dir) {
$contenu = glob($dir . "/*");
foreach ($contenu as $c) {
if (is_dir($c)) {
$this->addDirectory($c);
} else {
$this->addFile($c);
}
}
return true;
}
}
10 – Compresser un répertoire à la volée 2/3
Étudions plus en détails la méthode que nous venons d’écrire. Nous avons étendu l’objet ZipArchive (la classe de base) afin de lui rajouter la méthode addDirectory(). Par conséquent, nous n’initialiserons pas une instance de ZipArchive mais de ZipRecursif afin de pouvoir utiliser cette méthode. Nous ajoutons donc à la suite :
$zip = new ZipRecursif;
Cette classe héritera de toutes les méthodes de ZipArchive (les autres étapes restent donc valables) mais bénéficiera de la méthode supplémentaire addDirectory(). La méthode addDirectory() est une méthode récursive. Autrement dit, elle s’appelle elle-même durant son exécution.
11 – Compresser un répertoire à la volée 3/3
Nous souhaitons à présent ajouter automatiquement le répertoire « ./test » qui contient plusieurs fichiers contenus dans divers sous-répertoires.
Nous utilisons alors la fonction comme suit :
$zip->addDirectory(realpath("test"));
Étant donné que la méthode retourne true si elle a bien été exécutée, nous pouvons également effectuer un test :
if ($zip->addDirectory(realpath("test")) === true) {
echo "Le dossier a bien été compressé.";
} else {
echo "Une erreur est survenue.";
}
12 – fermeture de l’archive
Enfin, nous procédons à la fermeture de l’archive et à la sauvegarde des modifications effectuées au cours du script. Pour cela, nous utilisons la méthode close(). Nous ajoutons la ligne suivante à la fin du script :
$zip->close();