2013-07-11 18 views
5

Ho una cartella con alcuni file e sottocartelle all'interno. Come leggerò la directory e comprimo la cartella principale?cartella principale zip con sottocartella interna

Es:

maindirectory 
--- file 1 
--- file 2 
--- subdirectory 1 
------ file 3 
------ file 4 
--- subdirectory 2 
------ file 5 
------ file 6 

sto usando questo script:

function Zip($source, $destination, $include_dir = false) 
{ 

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

    if (file_exists($destination)) { 
     unlink ($destination); 
    } 

    $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_CHILD); 

     if ($include_dir) { 

      $arr = explode("/",$source); 
      $maindir = $arr[count($arr)- 1]; 

      $source = ""; 
      for ($i=0; $i < count($arr) - 1; $i++) { 
       $source .= '/' . $arr[$i]; 
      } 

      $source = substr($source, 1); 

      $zip->addEmptyDir($maindir); 

     } 

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

      // Ignore "." and ".." folders 
      if(in_array(substr($file, strrpos($file, '/')+1), array('.', '..'))) 
       continue; 

      $file = 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(); 
} 

e chiamare la funzione come questa:

Zip('image/data/','aaa.zip',false); 

Ma quello che ho capito è che la zip intera cartella C:. Quello che voglio è solo un documento zip all'interno della cartella image/data/.

Come posso formattare la directory corretta e le sue sottodirectory?

risposta

5

provare questo.

zipFile('image/data/','aaa.zip', true); 

/** 
* function zipFile. Creates a zip file from source to destination 
* 
* @param string $source Source path for zip 
* @param string $destination Destination path for zip 
* @param string|boolean $flag OPTIONAL If true includes the folder also 
* @return boolean 
*/ 
function zipFile($source, $destination, $flag = '') 
{ 
    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($flag) 
    { 
     $flag = basename($source) . '/'; 
     //$zip->addEmptyDir(basename($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 . '/', '', $flag.$file . '/')); 
      } 
      else if (is_file($file) === true) 
      { 
       $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file)); 
      } 
     } 
    } 
    else if (is_file($source) === true) 
    { 
     $zip->addFromString($flag.basename($source), file_get_contents($source)); 
    } 

    return $zip->close(); 
} 
+1

1 milione di grazie – AtanuCSE

+0

Può spiegare perché '$ flag'? Sto lavorando con percorsi completi e con un piccolo problema (la prima directory è vuota e mostra il percorso originale completo). – brasofilo

+0

@brasofilo '$ flag' qui include la directory di base qui così per qui comprime tutti i file e le cartelle di '' image/data/'' all'interno della directory 'data' –

1

Grazie ragazzi ... io a capire il problema alr ...

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 . '/', '', $flag.$file . '/')); //this should be commented so it wont include the main path 
     } 
     else if (is_file($file) === true) 
     { 
      $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file)); 
     } 
    } 
} 
0
 1- You should put all these code in a function 
     function readfile($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 . '/', '', $flag.$file . '/')); 
     } 
     else if (is_file($file) === true) 
     { 
      $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file)); 
     } 
    } 
} 
else if (is_file($source) === true) 
{ 
    $zip->addFromString($flag.basename($source), file_get_contents($source)); 
} 
    // here you would use recursive function 
    else if (is_dir($source) === true) 
{ 
    readfile($source); 
} 
} 

sintesi: se si trova un file, allora si farebbe operazione che si desidera e se si trova una directory per utilizzare la funzione ricorsiva per la directory di spostamento più.

2

ho modificato il codice di cui sopra perché non ero in grado di aggiungere le cartelle vuote e per evitare la C: guidare così

$otpt = "C:/xampp/htdocs/restricted/abc.zip"; 
$inpt = "C:/xampp/htdocs/Test/"; 


zipFile($inpt,$otpt, true); //Call to function 

function zipFile($source, $destination, $flag = '') 
{ 
    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($flag) 
    { 
     $flag = basename($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 (strpos($flag.$file,$source) !== false) { // this will add only the folder we want to add in zip 

       if (is_dir($file) === true) 
       { 
        $zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/')); 

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

    return $zip->close(); 
} 
0

Si dovrebbe aggiungere:

if(basename($file) === '.' || basename($file) === '..'){ 
    continue; 
} 

in questo modo:

if (is_dir($source) === true) { 
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); 
    foreach ($files as $file) { 
     if(basename($file) === '.' || basename($file) === '..'){ 
      continue; 
     } 
     $file = str_replace('\\', '/', realpath($file)); 
     if (is_dir($file) === true) { 
      $zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/')); 
     } else if (is_file($file) === true) { 
      $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file)); 
     } 
    } 
} else if (is_file($source) === true) { 
    $zip->addFromString($flag.basename($source), file_get_contents($source)); 
} 
0

Sarà più semplice e se si utilizza il metodo addfile invece di addfromstring

per vincere

public function ArchiveFile($path) 
    { 

     $path=realpath($path); 

     $zip = new \ZipArchive(); 
     $path= str_replace('/','\\', $path); 

     $nameFile = $path.'\\'.'letter'.time().'.zip'; 

     if ($zip->open($nameFile,\ZipArchive::CREATE)===TRUE){  




     if (is_dir($path)) 
     { 
      $pathSource= $path. '\\'; 
     $directory = new \RecursiveDirectoryIterator($path); 
     $files = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST); 
     } 




     foreach ($files as $name=>$file) 
     { 


      if (in_array(substr($name, strrpos($name,'\\')+1), array('.','..'))) 
      { 
       continue; 
      } 

     if  (is_file($name)===TRUE) { 

      $zip->addFile($name, str_replace($pathSource, "", $name)); 
      } 

     } 


      $zip->close(); 


     rename($nameFile, $nameFile.'.xlsx'); 
+0

Puoi aggiungere un breve esempio di OP alla tua risposta? – roelofs