我有一个包含一些文件和子文件夹的文件夹。我如何阅读目录并压缩主文件夹?
例如:
maindirectory
--- file 1
--- file 2
--- subdirectory 1
------ file 3
------ file 4
--- subdirectory 2
------ file 5
------ file 6
我正在使用这个脚本:
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();
}
我将这个函数称为:
Zip('image/data/','aaa.zip',false);
但我得到的是它压缩整个C:
文件夹。我想要的只是在image/data/
文件夹中压缩文档。
如何格式化正确的目录及其子目录?
答案 0 :(得分:5)
试试这个。
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 :(得分:2)
我编辑了上面的代码,因为我无法添加空文件夹以及避免使用C:驱动器
$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();
}
答案 2 :(得分:1)
谢谢你们......我想出了问题......
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));
}
}
}
答案 3 :(得分: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);
}
}
摘要: 如果你找到一个文件然后你会做你想要的操作,如果你找到一个目录,你将使用递归函数来遍历目录更多。
答案 4 :(得分:0)
你应该添加:
if(basename($file) === '.' || basename($file) === '..'){
continue;
}
像这样:
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));
}
答案 5 :(得分:0)
如果使用addfile方法而不是addfromstring
,它会更简单获胜
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');