Question

J'essaie d'utiliser le code suivant pour créer un fichier zip à partir d'un répertoire et le servir à l'utilisateur via un téléchargement http:

 // write the file
file_put_contents($path . "/index.html", $output);

// zip up the contents
chdir($path);
exec("zip -r {$course->name} ./");

$filename = "{$course->name}.zip";

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' .urlencode($filename));
header('Content-Transfer-Encoding: binary');

readfile($filename);

Je peux créer le fichier zip, mais le télécharger via http ne fonctionne pas. Si je télécharge le fichier zip créé à l'aide d'un client FTP, Stuffit Expander de Mac décompresse parfaitement les fichiers, mais si je le télécharge via http, le décompresseur mac crée une boucle infinie. Ce que je veux dire par là, c'est que le fichier que je télécharge s'appelle course.zip, puis décompresser le fichier donne course.zip.cpgz et le décompresser ce fichier donne encore cours.zip ... et ainsi de suite.

Quelqu'un a des idées?

Merci!

Était-ce utile?

La solution

  1. Ce n'est pas une bonne idée de ré-zipper le fichier chaque fois que c'est demandé. Essayez de faire cela uniquement si le fichier ZIP n’existe pas déjà.

  2. S'il s'agit d'un fichier volatile ou simplement d'un petit fichier que vous souhaitez transférer compressé, essayez plutôt d'utiliser ob_start ('ob_gzhandler') , plus simple, plus petit et plus propre. Le fichier est transféré compressé, mais il est enregistré dans son format d'origine par le client.

  3. Il est nécessaire de spécifier l'en-tête Content-Length pour permettre au téléchargeur de connaître la fin du fichier, permettant ainsi le contrôle de la progression, la détection de la corruption du fichier et permettant d'éviter le blocage de la session HTTP (si Connection est en mode Keep). Mode actif), peut-être que l'absence de cet en-tête est la cause du problème.

Autres conseils

J'ai eu ce problème et il s'est avéré qu'une nouvelle ligne était insérée au tout début du fichier zip téléchargé.

Résolu en utilisant les fonctions ob_clean et flush

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=".basename($archive_file_name));
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".filesize($archive_file_name));
    ob_clean();
    flush();
    echo readfile("$archive_file_name");

Comme suggéré par karim79 , je vais mettre mon commentaire en réponse: que se passera-t-il si vous modifiez le type MIME depuis application / octet-stream vers application / zip?

De plus, je vois que vous utilisez un programme zip en ligne de commande, mais vous ne vérifiez pas le succès du zip et ne vérifiez pas si le fichier existe avant de tenter de l'envoyer au navigateur de l'utilisateur final. . Essayez de coder en dur un nom de fichier, en utilisant manuellement zip pour garantir un fichier zip correctement formé, puis vérifiez si votre code va le recracher correctement sur votre navigateur.

Ce que vous constatez, c'est que l'utilitaire d'archivage ne reconnaît pas le fichier zip en tant que fichier zip et tente de compresser l'archive zip elle-même. La deuxième opération décompresse simplement le premier fichier créé, de sorte que vous ne l'ouvrez jamais réellement. Cela est dû au fait que le zip est corrompu.

Il est possible que le navigateur ait altéré le fichier zip (conversions newline, ça vous tente?) pendant le téléchargement. Comme indiqué, vérifiez le type MIME et utilisez l’en-tête php () pour définir le type MIME correct (application / zip).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top