2013-03-10 44 views
3

我有一个包含一个文件夹中的zip文件,包含多个文件夹和文件,像这样从文件夹中的文件:PHP - 提取一个zip

myfile.zip
-firstlevel
--folder1
- -folder2
--folder3
--file1
--file2

现在,我想提取使用PHP的ZipArchive这个文件,但没有“firstlevel “文件夹。目前,结果是这样的:

目的地/ firstlevel /文件夹1
目的地/ firstlevel /文件夹2
...

我想有是这样的结果是:

目的地/文件夹1
目的地/文件夹2
...

我已经试过extractTo,其生产的第一提及结果和复制(),如建议here,但这似乎不工作。

我当前的代码是在这里:

if($zip->open('myfile.zip') === true) { 
     $firstlevel = $zip->getNameIndex(0); 
     for($i = 0; $i < $zip->numFiles; $i++) { 
       $entry = $zip->getNameIndex($i); 
       $pos = strpos($entry, $firstlevel); 
       if ($pos !== false) { 
         $file = substr($entry, strlen($firstlevel)); 
         if(strlen($file) > 0){ 
           $files[] = $file; 
         } 
       } 
     } 
     //attempt 1 (extractTo): 
     //$zip->extractTo('./test', $files); 

     //attempt 2 (copy): 
     foreach($files as $filename){ 
       copy('zip://'.$firstlevel.'/'.$filename, 'test/'.$filename); 
     } 
} 

我如何能实现我的目标,结果呢?

+0

现在情况如何?这些文件是否始终与顶层文件夹一起出现,或者文件是否以不同的方式出现?你怎么知道顶层将永远是空的? – 2013-03-10 16:50:20

+0

准确地说:这些文件总是带有顶层文件夹,在服务器上解压缩文件时我不需要它们。 – Harmageddon 2013-03-10 20:11:37

回答

0

看看我的Quick Unzipper脚本。上传大型zip文件到服务器时,我写了这个供个人使用。这是一个备份,并且1000个文件永远使用FTP,因此使用zip文件更快。我使用Git和一切,但对我来说没有别的选择。我把这个php文件放在我想要文件去的目录中,并把zip文件放在同一个目录下。对于我的脚本,他们都必须在同一个目录下操作。因为我需要的东西都在同一个目录中,所以这是一种简单的方法来保护它以满足我的需求。

快速Unzipper:https://github.com/incomepitbull/QuickUnzipper/blob/master/unzip.php

我链接的文件,因为我不是展示回购,只是使解压打勾的代码。使用现代版本的PHP,不应该有任何不包含在您的设置中的任何内容。所以你不需要做任何服务器配置更改来使用它。

这里是它使用的ZipArchive类的PHP文件:http://php.net/manual/en/class.ziparchive.php

没有任何附带的方式做你想要什么,这是一种耻辱。所以我会将文件解压缩到一个临时目录,然后使用其他功能将内容复制到您想要的位置。因此,在使用ZipArchive时,如果文件夹名称未知,您将需要返回第一个项目以获取文件夹名称。如果该文件夹是已知的,即:每次都有相同的麻烦文件夹名称,那么您可以硬编码该名称。

我已经让它返回索引中的第一项。所以,如果你总是有一个拉链,里面有1个文件夹,并且该文件夹中的所有东西都可以工作。但是,如果您有一个没有整合到1个文件夹内的所有文件的压缩文件,它将会失败。我添加的代码将照顾你的问题。您需要添加更多逻辑来处理备选案例。

另外,从我们将其提取到临时目录进行“处理”时,您仍然会留下旧目录。所以我包括代码也删除它。

注意:该代码使用很多if来显示处理步骤,并打印出一条消息用于测试目的。您需要修改它以满足您的需求。

<?php 
public function copyDirectoryContents($source, $destination, $create=false) 
{ 
    if (! is_dir($source)) { 
     return false; 
    } 

    if (! is_dir($destination) && $create === true) { 
     @mkdir($destination); 
    } 

    if (is_dir($destination)) { 
     $files = array_diff(scandir($source), array('.','..')); 
     foreach ($files as $file) 
     { 
      if (is_dir($file)) { 
       copyDirectoryContents("$source/$file", "$destination/$file"); 
      } else { 
       @copy("$source/$file", "$destination/$file"); 
      } 
     } 
     return true; 
    } 
    return false; 
} 

public function removeDirectory($directory, $options=array()) 
{ 
    if(!isset($options['traverseSymlinks'])) 
     $options['traverseSymlinks']=false; 
    $files = array_diff(scandir($directory), array('.','..')); 
    foreach ($files as $file) 
    { 
     if (is_dir("$directory/$file")) 
     { 
      if(!$options['traverseSymlinks'] && is_link(rtrim($file,DIRECTORY_SEPARATOR))) { 
       unlink("$directory/$file"); 
      } else { 
       removeDirectory("$directory/$file",$options); 
      } 
     } else { 
      unlink("$directory/$file"); 
     } 
    } 
    return rmdir($directory); 
} 


$file = dirname(__FILE__) . '/file.zip';  // full path to zip file needing extracted 
$temp = dirname(__FILE__) . '/zip-temp';  // full path to temp dir to process extractions 
$path = dirname(__FILE__) . '/extracted';  // full path to final destination to put the files (not the folder) 

$firstDir = null;  // holds the name of the first directory 

$zip = new ZipArchive; 
$res = $zip->open($file); 
if ($res === TRUE) { 
    $firstDir = $zip->getNameIndex(0); 
    $zip->extractTo($temp); 
    $zip->close(); 
    $status = "<strong>Success:</strong> '$file' extracted to '$temp'."; 
} else { 
    $status = "<strong>Error:</strong> Could not extract '$file'."; 
} 

echo $status . '<br />'; 

if (empty($firstDir)) { 
    echo 'Error: first directory was empty!'; 
} else { 
    $firstDir = realpath($temp . '/' . $firstDir); 
    echo "First Directory: $firstDir <br />"; 
    if (is_dir($firstDir)) { 
     if (copyDirectoryContents($firstDir, $path)) { 
      echo 'Directory contents copied!<br />'; 
      if (removeDirectory($directory)) { 
       echo 'Temp directory deleted!<br />'; 
       echo 'Done!<br />'; 
      } else { 
       echo 'Error deleting temp directory!<br />'; 
      } 
     } else { 
      echo 'Error copying directory contents!<br />'; 
     } 
    } else { 
     echo 'Error: Could not find first directory'; 
    } 
} 
+0

请注意,我已经更新了几次我的答案。我添加了将zip解压缩到临时目录的代码,获取zip(您的目录)中第一个项目的名称,并使用该名称将其内容复制到您想要的位置。以及通过删除临时目录进行清理。 – 2015-01-26 12:56:19