2011-04-09 40 views
14

Necesito descargar imágenes de otros sitios web a mi servidor. Crea un archivo ZIP con esas imágenes. iniciar automáticamente la descarga del archivo ZIP creado. una vez que se completa la descarga, el archivo ZIP y las imágenes deben eliminarse de mi servidor.¿Cómo crear un archivo ZIP usando PHP y eliminarlo luego de que el usuario lo descargue?

En lugar de la descarga automática, un enlace de descarga también está bien. pero otra lógica permanece igual.

+3

¿Qué has probado hasta ahora? Stack Overflow no está aquí para proporcionar el código fuente para usted. Debe intentar resolver este problema usted mismo. Si encuentra un problema/problema específico, publique una pregunta específica después de la primera comprobación para ver si otro usuario aún no ha hecho la misma pregunta. –

Respuesta

13

Bueno, primero tendrá que crear el archivo zip, usando la clase ZipArchive.

A continuación, enviar:

  • Las cabeceras correctas, lo que indica al navegador que debe descargar algo como una postal - ver header() - hay un ejemplo de la página de ese manual que debe ayudar a
  • el contenido del archivo zip, utilizando readfile()

Y, por último, borrar el archivo zip desde el servidor, usando unlink().


Nota: como medida de seguridad, podría ser conveniente tener un script PHP se ejecuta automáticamente (por crontab, por lo general), que elimine los viejos archivos zip en el directorio temporal.

Esto en caso de que su script PHP normal se interrumpa a veces y no elimine el archivo temporal.

+0

¡Justo lo que necesitaba, gracias! – robertp

+0

Supongo que se bloqueará cuando el usuario pause la descarga, pero además esa es la mejor solución, creo – Lis

2

¿Alguna idea de cuántas descargas de archivos zip se interrumpen y deben continuarse?

Si las descargas continuas son un pequeño porcentaje de sus descargas, puede eliminar el archivo comprimido inmediatamente; mientras su servidor todavía esté enviando el archivo al cliente, permanecerá en el disco.

Una vez que el servidor cierra el descriptor de archivo, el recuento de referencias del archivo caerá a cero, y finalmente se liberarán sus bloques en el disco.

Pero, puede pasar una buena cantidad de tiempo recreando archivos zip si muchas descargas se interrumpen. Buena optimización barata si puede salirse con la suya.

+0

Gracias, esta es una buena información, realmente la única información necesaria para resolver el problema. No sé por qué no más votos al alza. – Bryan

1

Así es como he podido hacerlo en el pasado. Este código supone que ha escrito los archivos en una ruta especificada por la variable $path. Puede que tenga que hacer frente a algunos problemas de permisos en la configuración del servidor con el uso de exec

// write the files you want to zip up 
file_put_contents($path . "/file", $output); 

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

$filename = "{$name}.zip"; 

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

readfile($filename); 
0

En primer lugar, las imágenes se descargan desde webiste

entonces, con los archivos que ha descargado se creatae zipfile (gran tute) php

finalmente se envió a este archivo zip navegador usando readfile and headers (véase el ejemplo 1)

10
<?php 

Zip('some_directory/','test.zip'); 

if(file_exists('test.zip')){ 
    //Set Headers: 
    header('Pragma: public'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime('test.zip')) . ' GMT'); 
    header('Content-Type: application/force-download'); 
    header('Content-Disposition: inline; filename="test.zip"'); 
    header('Content-Transfer-Encoding: binary'); 
    header('Content-Length: ' . filesize('test.zip')); 
    header('Connection: close'); 
    readfile('test.zip'); 
    exit(); 
} 

if(file_exists('test.zip')){ 
    unlink('test.zip'); 

} 


function Zip($source, $destination) 
{ 
    if (!extension_loaded('zip') || !file_exists($source)) { 
     return false; 
    } 

    $zip = new ZipArchive(); 
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) { 
     return false; 
    } 

    $source = str_replace('\\', '/', realpath($source)); 

    if (is_dir($source) === true) 
    { 
     $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); 

     foreach ($files as $file) 
     { 
      $file = str_replace('\\', '/', realpath($file)); 

      if (is_dir($file) === true) 
      { 
       $zip->addEmptyDir(str_replace($source . '/', '', $file . '/')); 
      } 
      else if (is_file($file) === true) 
      { 
       $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file)); 
      } 
     } 
    } 
    else if (is_file($source) === true) 
    { 
     $zip->addFromString(basename($source), file_get_contents($source)); 
    } 

    return $zip->close(); 
} 

?> 
+7

El archivo comprimido nunca se eliminará. – Sven

+2

No es posible eliminar el archivo comprimido desde este código ya que no sabe cuándo se completará la descarga. Realmente necesitas eliminar el archivo a través de un trabajo cron. –

+0

¿No puede leer el archivo zip en una cadena y luego eliminar el archivo? Solo para archivos relativamente pequeños, por supuesto, pero aún así, parece un enfoque decente. – user1111929

1

Habilite su extensión php_curl; (php.ini), luego usa el código a continuación para crear el archivo zip. crear una carpeta clase y utilizando un código que figura a continuación:

<?php 
    include("class/create_zip.php"); 
    $create_zip  = new create_zip(); 
    //$url_path,$url_path2 you can use your directory path 
      $urls = array(
       '$url_path/file1.pdf',   
       '$url_path2/files/files2.pdf' 
       ); // file paths 


      $file_name  = "vin.zip"; // zip file default name 
      $file_folder = rand(1,1000000000); // folder with random name 
      $create_zip->create_zip($urls,$file_folder,$file_name); 
      $create_zip->delete_directory($file_folder); //delete random folder 

      if(file_exists($file_name)){ 
      $temp = file_get_contents($file_name);  
      unlink($file_name); 
      }  

      echo $temp; 

    ?> 

crear una carpeta clase y utilizando un código que figura a continuación:

<?php 

    class create_zip{ 

     function create_zip($urls,$file_folder,$file_name){ 

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

       $mkdir = mkdir($file_folder); 

       $zip = new ZipArchive; 
       $zip->open($file_name, ZipArchive::CREATE); 

       foreach ($urls as $url) 
       { 
        $path=pathinfo($url);  
        $path = $file_folder.'/'.$path['basename']; 
        $zip->addFile($path);  
        $fileopen = fopen($path, 'w');  
        $init = curl_init($url);  
        curl_setopt($init, CURLOPT_FILE, $fileopen);  
        $data = curl_exec($init);  
        curl_close($init);  
        fclose($fileopen); 
       } 

       $zip->close(); 


      } 

      function delete_directory($dirname) 
      { 
       if (is_dir($dirname)) 
       $dir_handle = opendir($dirname); 
       if (!$dir_handle) 
       return false; 
        while($file = readdir($dir_handle)) 
        { 
         if ($file != "." && $file != "..") 
         { 
          if (!is_dir($dirname."/".$file))    
          unlink($dirname."/".$file);   
          else    
          delete_directory($dirname.'/'.$file);   
         }  
        } 
       closedir($dir_handle);  
       rmdir($dirname);  
       return true; 
      } 



    } 

    ?> 
0

otra solución: Eliminar archivos pasados ​​antes de la creación nuevo archivo zip:

// Delete past zip files script 
    $files = glob('*.zip'); //get all file names in array 
    $currentTime = time(); // get current time 
    foreach($files as $file){ // get file from array 
     $lastModifiedTime = filemtime($file); // get file creation time 

     // get how old is file in hours: 
     $timeDiff = abs($currentTime - $lastModifiedTime)/(60*60); 

     //check if file was modified before 1 hour: 
     if(is_file($file) && $timeDiff > 1) 
      unlink($file); //delete file 
    } 
Cuestiones relacionadas