2010-06-20 15 views
16

Tengo un script PHP que crea un archivo zip sobre la marcha y obliga al navegador a descargar el archivo zip. La pregunta es: ¿podría escribir directamente el archivo zip en un flujo de salida que está conectado al navegador del usuario en lugar de guardarlo como un archivo real en el servidor primero y luego enviar el archivo?Zip Stream en PHP

Gracias de antemano.

+1

La respuesta a esta pregunta es aquí: http://stackoverflow.com/a/4357904/416630 – Lee

Respuesta

5

Si está utilizando el zip extension, la respuesta parece ser "no". El close method in the ZipArchive class es lo que desencadena una escritura, y parece querer escribir en un archivo. Usted podría tener un poco de suerte usando Streams para simular un archivo, pero luego está guardando todo en la memoria, y aún no podría enviarlo hasta que haya terminado de agregar archivos.

Si usted está teniendo problemas con los tiempos de espera y otros problemas al tener una espera de usuario para el archivo zip que se cree, trate de un proceso de descarga de múltiples pasos:

  1. selecciones del usuario lo que recogen para crear el zip
  2. Se llevan a una página de estado que usa llamadas ajax para crear realmente el archivo zip en segundo plano. Una bonita y distraída animación debería mantener su atención.
  3. Después de que los procesos en segundo plano crean el zip, el usuario se redirige a un script que realiza la descarga/se redirige al archivo.
-1

No, tiene que usar un archivo temporal, como en here.

11

Si el servidor Web se está ejecutando Linux, entonces usted puede hacerlo sin la transmisión de un archivo temporal que se genera. En win32 puede que necesite usar Cygwin o algo similar.

Si usa "-" como el nombre del archivo zip, se comprimirá a stdout. A partir de ahí, es bastante fácil redirigir esa secuencia usando popen(). El argumento "-q" simplemente le dice a zip que no muestre el texto de estado que normalmente tendría. Consulte la página de manual de zip (1) para obtener más información.

<? 
    $zipfilename = "zip_file_name.zip"; 

    if(isset($files)) unset($files); 

    $target = "/some/directory/of/files/you/want/to/zip"; 

    $d = dir($target); 

    while(false !== ($entry = $d->read())) 
    { 
     if(substr($entry, 0, 1) != "." && !is_dir($entry)) 
     { 
     $files[] = $entry; 
     } 
    } 

    header("Content-Type: application/x-zip"); 
    header("Content-Disposition: attachment; filename=\"$zipfilename\""); 

    $filespec = ""; 

    foreach($files as $entry) 
    { 
     $filespec .= "\"$entry\" "; 
    } 

    chdir($target); 

    $stream = popen("/usr/bin/zip -q - $filespec", "r"); 

    if($stream) 
    { 
     fpassthru($stream); 
     fclose($stream); 
    } 
?> 
1

Sí, puede transmitir directamente la cremallera al cliente utilizando este git representante: Zip Stream Large Files

+0

Parece que no funciona bajo Windows – Jerry