grupo de jesse
Estoy usando la clase ZipArchive de PHP para crear un archivo zip que contiene fotos y luego enviarlo al navegador para su descarga. Aquí está mi código:
/**
* Grabs the order, packages the files, and serves them up for download.
*
* @param string $intEntryID
* @return void
* @author Jesse Bunch
*/
public static function download_order_by_entry_id($intUniqueID) {
$objCustomer = PhotoCustomer::get_customer_by_unique_id($intUniqueID);
if ($objCustomer):
if (!class_exists('ZipArchive')):
trigger_error('ZipArchive Class does not exist', E_USER_ERROR);
endif;
$objZip = new ZipArchive();
$strZipFilename = sprintf('%s/application/tmp/%s-%s.zip', $_SERVER['DOCUMENT_ROOT'], $objCustomer->getEntryID(), time());
if ($objZip->open($strZipFilename, ZIPARCHIVE::CREATE) !== TRUE):
trigger_error('Unable to create zip archive', E_USER_ERROR);
endif;
foreach($objCustomer->arrPhotosRequested as $objPhoto):
$filename = PhotoCart::replace_ee_file_dir_in_string($objPhoto->strHighRes);
$objZip->addFile($filename,sprintf('/press_photos/%s-%s', $objPhoto->getEntryID(), basename($filename)));
endforeach;
$objZip->close();
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($strZipFilename)).' GMT', TRUE, 200);
header('Cache-Control: no-cache', TRUE);
header('Pragma: Public', TRUE);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT', TRUE);
header('Content-Length: '.filesize($strZipFilename), TRUE);
header('Content-disposition: attachment; filename=press_photos.zip', TRUE);
header('Content-Type: application/octet-stream', TRUE);
ob_start();
readfile($strZipFilename);
ob_end_flush();
exit;
else:
trigger_error('Invalid Customer', E_USER_ERROR);
endif;
}
Este código funciona muy bien con todos los navegadores excepto IE. En IE, el archivo se descarga correctamente, pero el archivo zip está vacío. Cuando intento extraer los archivos, Windows me dice que el archivo zip está dañado. Alguien ha tenido este problema antes?
Editar Actualización: después de la sugerencia de @profitphp, cambié mis encabezados a esto:
header("Cache-Control: public");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
//header("Content-Description: File Transfer");
//header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=\"pressphotos.zip\"");
//header("Content-Transfer-Encoding: binary");
header("Content-length: " . filesize($strZipFilename));
Además, aquí hay una captura de pantalla del error en Windows después de abrir con Firefox:
Este error ocurre tanto en IE como en Firefox en Windows. Funciona bien en Mac. Además, en Windows, el tamaño del archivo parece ser correcto:
Editar #2 Este problema está resuelto. Vea mi respuesta a continuación.
CWSpear
Tuve el mismo problema y mi solución fue similar a la respuesta correcta en este hilo. Cuando coloca un archivo en el archivo, no puede tener archivos absolutos (archivos que comienzan con una barra inclinada) o, de lo contrario, no se abrirá en Windows por algún motivo.
Entonces funcionó no porque él (Jesse Bunch, la respuesta seleccionada en el momento de escribir este artículo) eliminó la carpeta contenedora, sino porque eliminó la barra inclinada inicial.
Resolví el problema cambiando
$zip->addFile($file, $file); // $file is something like /path/to/file.png
a
// we make file relative by removing beginning slash so it will open in Windows
$zip->addFile($file, ltrim($file, "https://stackoverflow.com/"));
¡y luego pudo abrirse en Windows!
Esa es probablemente la misma razón por la que funciona pclzip (la respuesta de Plahcinski). Apuesto a que elimina automáticamente la barra inicial.
No me habría dado cuenta de esto sin un comentario particular en el PHP ZipArchive::addFile
página de documentación.
-
Este fue el problema para mí, ayudó mucho
– Jake N.
15/03/2016 a las 22:00
Recientemente tuve un problema similar al que describiste. Descubrí que ZipArchive es inestable en el mejor de los casos.
Resolví mis problemas con esta biblioteca simple.
http://www.phpconcept.net/pclzip
include_once('libs/pclzip.lib.php');
…
function zip($source, $destination){
$zipfile = new PclZip($destination);
$v_list = $zipfile->create($source, '', $source); }
$fuente = carpeta que quería comprimir $destino = ubicación del archivo zip
Pasé 2 días buscando en ZipArchive y luego resolví todos los problemas con PCLZip en 5 minutos.
Espero que esto te ayude a ti y a cualquier otra persona que tenga este problema (ya que está cerca del resultado principal de Google sobre el problema).
-
en un entorno de ventana. En mi página web, desafortunadamente funcionó muy bien: solo comprimió un archivo en lugar de varios archivos,
– Dev.Jaap
16/04/2012 a las 18:55
-
funcionó para mí en Windows. como dijiste, casi una hora mirando ZipArchive, y esto funcionó en 2 minutos. ¡gracias!
– Flón
26 de agosto de 2013 a las 14:02
-
Gran biblioteca. Para usarlo en el servidor PHP7.1, simplemente cambie el método “PclZip” a “__construct” y agregue “(int)” donde se requiere el número entero.
– Foca
17 de julio de 2017 a las 16:34
-
Enlace muerto para la biblioteca.
– Ravi Mattar
18 de agosto de 2022 a las 14:57
Todas estas sugerencias pueden ayudarte, pero en mi caso necesito escribir un ob_clean(); antes del primer encabezado (”); porque algún archivo que incluí antes imprimió algunos caracteres que rompieron el archivo zip en Windows.
$zip=new ZipArchive();
$zip->open($filename, ZIPARCHIVE::CREATE);
$zip->addFile($file_to_attach,$real_file_name_to_attach);
$zip->close();
ob_clean();
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header('Content-Type: application/x-download');
header('Content-Disposition: attachment; filename="file.zip"');
readfile($filename);
exit;
-
Esto funcionó para mí, probé todo lo demás sin suerte.
– llanato
27 de julio de 2015 a las 13:34
-
Este también funcionó para mí. También probé todo lo demás. Esta debería ser la respuesta aceptada. Nota: Solo tuve que agregar la línea: ob_clean() para que mi código funcionara. Pasé una hora o dos tratando de obtener archivos zip que pudieran abrirse.
– mikekehrli
10 jun 2021 a las 21:32
Ok, después de mucha lucha, descubrí el problema. El problema proviene de la siguiente línea de código:
$objZip->addFile($filename,sprintf('/press_photos/%s-%s', $objPhoto->getEntryID(), basename($filename)));
Por alguna razón, el /press_photos/
parte de esa ruta para el nombre del archivo local (interno) dentro del archivo zip estaba causando que Windows pensara que el archivo zip estaba dañado. Después de modificar la línea para que se parezca a lo que se muestra a continuación, Windows abrió los archivos zip correctamente. Uf.
$objZip->addFile($filename,sprintf('%s-%s', $objPhoto->getEntryID(), basename($filename)));
El uso de caracteres especiales, como guiones bajos, causa problemas porque ZipArchive requiere nombres de entrada codificados en IBM850. Ver comentarios en el manual de PHP en línea: http://www.php.net/manual/en/function.ziparchive-addfile.php#95725 .
-
Tenía un nombre de archivo zip largo con espacios, guiones y caracteres de fecha. Resulta que una vez que cambié los nombres de archivo a algo simple, como export.zip, funcionó bien.
–Nathan Hangen
21 de marzo de 2014 a las 14:38
beneficiophp
He tenido problemas con esto antes. Intente quitar el encabezado del tipo de contenido. aquí está el código que se me ocurrió que funcionó en IE y FF. Observe las líneas comentadas, estaba teniendo los mismos problemas con diferentes combos de los que estaban activados.
header("Cache-Control: public");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
//header("Content-Description: File Transfer");
//header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=\"adwords-csv.zip\"");
//header("Content-Transfer-Encoding: binary");
header("Content-length: " . filesize($filename));
-
Tenía un nombre de archivo zip largo con espacios, guiones y caracteres de fecha. Resulta que una vez que cambié los nombres de archivo a algo simple, como export.zip, funcionó bien.
–Nathan Hangen
21 de marzo de 2014 a las 14:38
Marca
Hace una hora que tengo este problema. Después de probar 10 soluciones diferentes, lo resolví asegurándome de que el script exista después de generar el archivo ZIP:
readfile($zip_name);
unlink($zip_name);
**exit();**
-
Esta es la solución que funcionó para mí después de probar la mayoría de las cosas enumeradas anteriormente
– Michael Renison
8 dic 2022 a las 15:43
Tenía el mismo problema y esta respuesta fue la solución para mí: [ZIP Archive sent by PHP is corrupted][1] [1]: stackoverflow.com/a/13528263/557311
– MaRmAR
27 de febrero de 2015 a las 16:02