[英]How can I extract files from a zip folder using PHP while retaining the files original timestamps?
[英]php - extract files from folder in a zip
我有一个包含一个文件夹的zip文件,其中包含更多文件夹和文件,如下所示:
myfile.zip
-第一级
--folder1
--folder2
--folder3
--file1
--file2
现在,我想使用PHP ZipArchive提取此文件,但没有“firstlevel”文件夹。 目前,结果如下:
目的地/ firstlevel / folder1中
目的地/ firstlevel /文件夹2
...
我希望得到的结果如下:
目的地/文件夹1
目的地/文件夹2
...
我已经尝试过extractTo,它产生了第一个提到的结果,而copy()就像这里所建议的那样,但这似乎根本不起作用。
我目前的代码在这里:
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);
}
}
我怎样才能达到我的目标?
看看我的Quick Unzipper脚本。 在将大型zip文件上传到服务器时,我暂时将其写入个人用途。 这是一个备份,1,000个文件永远使用FTP,所以使用zip文件更快。 我使用Git和所有东西,但我没有其他选择。 我将这个php文件放在我想要文件的目录中,并将zip文件放在同一目录中。 对于我的脚本,它们都必须在同一目录中运行。 这是一种简单的方法来保护它满足我的需求,因为我需要的是同一个目录。
Quick Unzipper: https : //github.com/incomepitbull/QuickUnzipper/blob/master/unzip.php
我链接了文件,因为我没有展示repo,只是解压缩的代码。 使用现代版本的PHP,您的设置中不应包含任何内容。 因此,您不需要进行任何服务器配置更改即可使用此功能。
以下是它使用的ZipArchive类的PHP Doc: http : //php.net/manual/en/class.ziparchive.php
没有任何包含的方法来做你想要的,这是一种耻辱。 所以我将文件解压缩到临时目录,然后使用另一个函数将内容复制到你想要的位置。 因此,在使用ZipArchive时,如果未知,则需要返回第一个项目以获取文件夹名称。 如果文件夹是已知的,即:每次都是相同的讨厌文件夹名称,那么您可以对该名称进行硬编码。
我让它从索引中返回第一个项目。 因此,如果你总是有一个带有1个文件夹的拉链,以及该文件夹中的所有内容,这将有效。 但是,如果你有一个zip文件而没有在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';
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.