open($tmpzip, ZipArchive::CREATE) !== true) { throw new IOException("unable to create $tmpzip"); } $this->filename = $filename; $this->tmpzip = $tmpzip; $this->zip = $zip; $this->deletes = [$tmpzip]; } private $filename; private $tmpzip; private $zip; private $deletes; /** * ajouter une entrée dans le fichier zip avec le nom spécifié * * un fichier temporaire est préparé, et une instance permettant d'y écrire * est retournée. c'est ce fichier qui sera inséré dans le fichier zip. */ function newFile(string $entryname): IWriter { $tmpfile = file::temp("zipe", static::TMPDIR); $this->deletes[] = $tmpfile; $outw = new FileWriter($tmpfile, "wb"); if ($this->zip->addFile($tmpfile, $entryname) !== true) { $outw->close(); throw new IOException("unable to add $entryname"); } return $outw; } /** * ajouter une entrée dans le fichier zip construite à partir du fichier * spécifié. ce fichier doit exister jusqu'à ce que la méthode {@link send()} * soit appelée */ function addFile(string $file, ?string $entryname=null): void { if ($entryname === null) $entryname = basename($file); if ($this->zip->addFile($file, $entryname) !== true) { throw new IOException("unable to add $file"); } } /** * ajouter une entrée dans le fichier zip construite à partir de la chaine * spécifiée */ function addString(string $entryname, string $content): void { if ($this->zip->addFromString($entryname, $content) !== true) { throw new IOException("unable to add $entryname"); } } /** finaliser le fichier zip et le streamer vers le client */ function send(): void { $this->zip->close(); $zipf = file::open($this->tmpzip, "rb"); foreach ($this->deletes as $delete) { unlink($delete); } header("Content-Type: application/zip"); header("Content-Disposition: attachment; filename=\"$this->filename\""); fpassthru($zipf); } }