我有一个名为“data”的文件夹。此“data”文件夹包含文件“filecontent.txt”和另一个名为“Files”的文件夹。 “Files”文件夹包含“info.txt”文件。 所以它是文件夹结构中的一个文件夹。
我必须将此文件夹“data”(使用php)以及其中的文件和文件夹压缩,然后下载压缩文件。
我已尝试http://www.php.net/manual/en/zip.examples.php处提供的示例 这些例子不起作用。我的PHP版本是5.2.10
请帮忙。
我已经写了这段代码。
<?php
$zip = new ZipArchive;
if ($zip->open('check/test2.zip',ZIPARCHIVE::CREATE) === TRUE) {
if($zip->addEmptyDir('newDirectory')) {
echo 'Created a new directory';
} else {
echo 'Could not create directory';
}
$zipfilename="test2.zip";
$zipname="check/test2.zip";
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=check/test1.zip'); //header('Content-Length: ' . filesize( $zipfilename));
readfile($zipname); //$zip->close(); } else { echo failed';
}
?>
文件已下载但无法解压缩
答案 0 :(得分:5)
您需要以递归方式在目录中添加文件。像这样(未经测试):
function createZipFromDir($dir, $zip_file) {
$zip = new ZipArchive;
if (true !== $zip->open($zip_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
return false;
}
zipDir($dir, $zip);
return $zip;
}
function zipDir($dir, $zip, $relative_path = DIRECTORY_SEPARATOR) {
$dir = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if (file === '.' || $file === '..') {
continue;
}
if (is_file($dir . $file)) {
$zip->addFile($dir . $file, $file);
} elseif (is_dir($dir . $file)) {
zipDir($dir . $file, $zip, $relative_path . $file);
}
}
}
closedir($handle);
}
然后拨打$zip = createZipFromDir('/tmp/dir', 'files.zip');
为了获得更多胜利,我建议您阅读SPL DirectoryIterator
here
答案 1 :(得分:4)
将所有子文件夹和子文件放在其结构中:
<?php
$the_folder = 'path/foldername';
$zip_file_name = 'archived_name.zip';
$download_file= true;
//$delete_file_after_download= true; doesnt work!!
class FlxZipArchive extends ZipArchive {
/** Add a Dir with Files and Subdirs to the archive;;;;; @param string $location Real Location;;;; @param string $name Name in Archive;;; @author Nicolas Heimann;;;; @access private **/
public function addDir($location, $name) {
$this->addEmptyDir($name);
$this->addDirDo($location, $name);
} // EO addDir;
/** Add Files & Dirs to archive;;;; @param string $location Real Location; @param string $name Name in Archive;;;;;; @author Nicolas Heimann
* @access private **/
private function addDirDo($location, $name) {
$name .= '/';
$location .= '/';
// Read all Files in Dir
$dir = opendir ($location);
while ($file = readdir($dir))
{
if ($file == '.' || $file == '..') continue;
// Rekursiv, If dir: FlxZipArchive::addDir(), else ::File();
$do = (filetype( $location . $file) == 'dir') ? 'addDir' : 'addFile';
$this->$do($location . $file, $name . $file);
}
} // EO addDirDo();
}
$za = new FlxZipArchive;
$res = $za->open($zip_file_name, ZipArchive::CREATE);
if($res === TRUE)
{
$za->addDir($the_folder, basename($the_folder));
$za->close();
}
else { echo 'Could not create a zip archive';}
if ($download_file)
{
ob_get_clean();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=" . basename($zip_file_name) . ";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($zip_file_name));
readfile($zip_file_name);
//deletes file when its done...
//if ($delete_file_after_download)
//{ unlink($zip_file_name); }
}
?>
答案 2 :(得分:2)
几天前我必须做同样的事情,这就是我所做的。
1)检索文件/文件夹结构并填充项目数组。每个项目都是文件或文件夹,如果是文件夹,则以相同的方式将其内容检索为项目。
2)解析该数组并生成zip文件。
将我的代码放在下面,您当然必须根据应用程序的设置进行调整。
// Get files
$items['items'] = $this->getFilesStructureinFolder($folderId);
$archiveName = $baseDir . 'temp_' . time(). '.zip';
if (!extension_loaded('zip')) {
dl('zip.so');
}
//all files added now
$zip = new ZipArchive();
$zip->open($archiveName, ZipArchive::OVERWRITE);
$this->fillZipRecursive($zip, $items);
$zip->close();
//outputs file
if (!file_exists($archiveName)) {
error_log('File doesn\'t exist.');
echo 'Folder is empty';
return;
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=" . basename($archiveName) . ";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($archiveName));
readfile($archiveName);
//deletes file when its done...
unlink($archiveName);
用于填补&amp;解析:
/**
*
* Gets all the files recursively within a folder and keeps the structure.
*
* @param int $folderId The id of the folder from which we start the search
* @return array $tree The data files/folders data structure within the given folder id
*/
public function getFilesStructureinFolder($folderId) {
$result = array();
$query = $this->db->query('SELECT * FROM xx WHERE deleted = 0 AND status = 1 AND parent_folder_id = ? ORDER BY name ASC', $folderId);
$folders = $query->result();
foreach($folders as $folder) {
$folderItem = array();
$folderItem['type'] = 'folder';
$folderItem['obj'] = $folder;
$folderItem['items'] = $this->getFilesStructureinFolder($folder->id);
$result[] = $folderItem;
}
$query = $this->db->query('SELECT * FROM xx WHERE deleted = 0 AND xx = ? AND status = 1 ORDER BY name ASC', $folderId);
$files = $query->result();
foreach ($files as $file) {
$fileItem = array();
$fileItem['type'] = 'file';
$fileItem['obj'] = $file;
$result[] = $fileItem;
}
return $result;
}
/**
* Fills zip file recursively
*
* @param ZipArchive $zip The zip archive we are filling
* @param Array $items The array representing the file/folder structure
* @param String $zipPath Local path within the zip
*
*/
public function fillZipRecursive($zip, $items, $zipPath = '') {
$baseDir = $this->CI->config->item('xxx');
foreach ($items['items'] as $item) {
//Item is a file
if ($item['type'] == 'file') {
$file = $item['obj'];
$fileName = $baseDir . '/' . $file->fs_folder_id . '/' . $file->file_name;
if (trim($file->file_name) == '' || !file_exists($fileName))
continue;
$zip->addFile($fileName, $zipPath.''.$file->file_name);
}
//Item is a folder
else if ($item['type'] == 'folder') {
$folder = $item['obj'];
$zip->addEmptyDir($zipPath.''.$folder->name);
//Folder probably has items in it!
if (!empty($item['items']))
$this->fillZipRecursive($zip, $item, $zipPath.'/'.$folder->name.'/');
}
}
}
答案 3 :(得分:1)
查看链接的重复项。另一个经常被忽视和特别懒惰的选择是:
exec("zip -r data.zip data/");
header("Content-Type: application/zip");
readfile("data.zip"); // must be a writeable location though
答案 4 :(得分:1)
使用TbsZip类创建新的zip存档。 TbsZip很简单,它不使用临时文件,没有zip EXE,它没有依赖性,并且有一个下载功能,可以将存档作为下载文件刷新。
您只需在文件夹树下循环并添加归档中的所有文件,然后将其刷新。
代码示例:
$zip = new clsTbsZip(); // instantiate the class
$zip->CreateNew(); // create a virtual new zip archive
foreach (...) { // your loop to scann the folder tree
...
// add the file in the archive
$zip->FileAdd($FileInnerName, $LocalFilePath, TBSZIP_FILE);
}
// flush the result as an HTTP download
$zip->Flush(TBSZIP_DOWNLOAD, 'my_archive.zip');
归档中添加的文件将在Flush()方法中按顺序压缩。因此,您的存档可以包含许多子文件,这不会增加PHP内存。