[재귀 적으로] PHP에서 디렉토리를 압축하는 방법?
PHP[재귀 적으로] PHP에서 디렉토리를 압축하는 방법?
디렉토리는 다음과 같습니다.
home/
file1.html
file2.html
Another_Dir/
file8.html
Sub_Dir/
file19.html
PHPMyAdmin http://trac.seagullproject.org/browser/branches/0.6-bugfix/lib/other/Zip.php에서 사용 된 동일한 PHP Zip 클래스를 사용하고 있습니다. 파일보다는 디렉터리를 압축하는 방법을 잘 모르겠습니다. 여기 내가 지금까지 가지고있는 것이있다.
$aFiles = $this->da->getDirTree($target);
/* $aFiles is something like, path => filetime
Array
(
[home] =>
[home/file1.html] => 1251280379
[home/file2.html] => 1251280377
etc...
)
*/
$zip = & new Zip();
foreach( $aFiles as $fileLocation => $time ){
$file = $target . "/" . $fileLocation;
if ( is_file($file) ){
$buffer = file_get_contents($file);
$zip->addFile($buffer, $fileLocation);
}
}
THEN_SOME_PHP_CLASS::toDownloadData($zip); // this bit works ok
하지만 다운로드 한 ZIP 파일의 압축을 풀려고하면 "허용되지 않는 작업"이 발생합니다.
이 오류는 파일 압축 해제 명령 줄을 통해 압축을 풀 때 내 Mac에서 압축을 풀려고 할 때만 발생합니다. 다운로드시 특정 컨텐츠 유형 (현재 'application / zip')을 보내야합니까?
해결법
-
==============================
1.다음은 파일이나 디렉토리를 재귀 적으로 압축 할 수있는 간단한 함수이며,로드 할 zip 확장 만 있으면됩니다.
다음은 파일이나 디렉토리를 재귀 적으로 압축 할 수있는 간단한 함수이며,로드 할 zip 확장 만 있으면됩니다.
function Zip($source, $destination) { 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 (is_dir($source) === true) { $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); 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('/folder/to/compress/', './compressed.zip');
-
==============================
2.ZipArchive의 확장으로 구현 된 또 다른 재귀 적 디렉토리 트리 보관. 보너스로, 단일 명령문 트리 압축 도우미 기능이 포함되어 있습니다. 선택적 localname은 다른 ZipArchive 함수와 마찬가지로 지원됩니다. 추가 할 오류 처리 코드 ...
ZipArchive의 확장으로 구현 된 또 다른 재귀 적 디렉토리 트리 보관. 보너스로, 단일 명령문 트리 압축 도우미 기능이 포함되어 있습니다. 선택적 localname은 다른 ZipArchive 함수와 마찬가지로 지원됩니다. 추가 할 오류 처리 코드 ...
class ExtendedZip extends ZipArchive { // Member function to add a whole file system subtree to the archive public function addTree($dirname, $localname = '') { if ($localname) $this->addEmptyDir($localname); $this->_addTree($dirname, $localname); } // Internal function, to recurse protected function _addTree($dirname, $localname) { $dir = opendir($dirname); while ($filename = readdir($dir)) { // Discard . and .. if ($filename == '.' || $filename == '..') continue; // Proceed according to type $path = $dirname . '/' . $filename; $localpath = $localname ? ($localname . '/' . $filename) : $filename; if (is_dir($path)) { // Directory: add & recurse $this->addEmptyDir($localpath); $this->_addTree($path, $localpath); } else if (is_file($path)) { // File: just add $this->addFile($path, $localpath); } } closedir($dir); } // Helper function public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '') { $zip = new self(); $zip->open($zipFilename, $flags); $zip->addTree($dirname, $localname); $zip->close(); } } // Example ExtendedZip::zipTree('/foo/bar', '/tmp/archive.zip', ZipArchive::CREATE);
-
==============================
3.세 번째 인수를 취하기 위해 Alix Axel의 대답을 편집했습니다.이 세 번째 인수를 true로 설정하면 모든 파일이 zip 폴더에 직접 저장되는 것이 아니라 기본 디렉토리 아래에 추가됩니다.
세 번째 인수를 취하기 위해 Alix Axel의 대답을 편집했습니다.이 세 번째 인수를 true로 설정하면 모든 파일이 zip 폴더에 직접 저장되는 것이 아니라 기본 디렉토리 아래에 추가됩니다.
zip 파일이 있으면 파일도 삭제됩니다.
예:
Zip('/path/to/maindirectory','/path/to/compressed.zip',true);
세 번째 인수 진정한 zip 구조 :
maindirectory --- file 1 --- file 2 --- subdirectory 1 ------ file 3 ------ file 4 --- subdirectory 2 ------ file 5 ------ file 6
세 번째 인수 인 false 또는 missing zip structure :
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_FIRST); 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(); }
-
==============================
4.사용법 : thisfile.php? dir =. / path / to / folder (압축을 푼 후에도 다운로드가 시작됩니다 :)
사용법 : thisfile.php? dir =. / path / to / folder (압축을 푼 후에도 다운로드가 시작됩니다 :)
<?php $exclude_some_files= array( 'mainfolder/folder1/filename.php', 'mainfolder/folder5/otherfile.php' ); //***************built from https://gist.github.com/ninadsp/6098467 ****** class ModifiedFlxZipArchive extends ZipArchive { public function addDirDoo($location, $name , $prohib_filenames=false) { if (!file_exists($location)) { die("maybe file/folder path incorrect");} $this->addEmptyDir($name); $name .= '/'; $location.= '/'; $dir = opendir ($location); // Read all Files in Dir while ($file = readdir($dir)){ if ($file == '.' || $file == '..') continue; if (!in_array($name.$file,$prohib_filenames)){ if (filetype( $location . $file) == 'dir'){ $this->addDirDoo($location . $file, $name . $file,$prohib_filenames ); } else { $this->addFile($location . $file, $name . $file); } } } } public function downld($zip_name){ 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_name) . ";" ); header("Content-Transfer-Encoding: binary"); header("Content-Length: " . filesize($zip_name)); readfile($zip_name); } } //set memory limits set_time_limit(3000); ini_set('max_execution_time', 3000); ini_set('memory_limit','100M'); $new_zip_filename='down_zip_file_'.rand(1,1000000).'.zip'; // Download action if (isset($_GET['dir'])) { $za = new ModifiedFlxZipArchive; //create an archive if ($za->open($new_zip_filename, ZipArchive::CREATE)) { $za->addDirDoo($_GET['dir'], basename($_GET['dir']), $exclude_some_files); $za->close(); }else {die('cantttt');} if (isset($_GET['dir'])) { $za = new ModifiedFlxZipArchive; //create an archive if ($za->open($new_zip_filename, ZipArchive::CREATE)) { $za->addDirDoo($_GET['dir'], basename($_GET['dir']), $exclude_some_files); $za->close(); }else {die('cantttt');} //download archive //on the same execution,this made problems in some hostings, so better redirect //$za -> downld($new_zip_filename); header("location:?fildown=".$new_zip_filename); exit; } if (isset($_GET['fildown'])){ $za = new ModifiedFlxZipArchive; $za -> downld($_GET['fildown']); } ?>
-
==============================
5.이 링크를 사용해보십시오. <- MORE SOURCE CODE DEERE
이 링크를 사용해보십시오. <- MORE SOURCE CODE DEERE
/** Include the Pear Library for Zip */ include ('Archive/Zip.php'); /** Create a Zipping Object... * Name of zip file to be created.. * You can specify the path too */ $obj = new Archive_Zip('test.zip'); /** * create a file array of Files to be Added in Zip */ $files = array('black.gif', 'blue.gif', ); /** * creating zip file..if success do something else do something... * if Error in file creation ..it is either due to permission problem (Solution: give 777 to that folder) * Or Corruption of File Problem.. */ if ($obj->create($files)) { // echo 'Created successfully!'; } else { //echo 'Error in file creation'; } ?>; // We'll be outputting a ZIP header('Content-type: application/zip'); // It will be called test.zip header('Content-Disposition: attachment; filename="test.zip"'); //read a file and send readfile('test.zip'); ?>;
-
==============================
6.여기에 내 코드는 폴더와 하위 폴더 및 해당 파일을 압축하여 zip 형식으로 다운로드 할 수있게합니다.
여기에 내 코드는 폴더와 하위 폴더 및 해당 파일을 압축하여 zip 형식으로 다운로드 할 수있게합니다.
function zip() { $source='path/folder'// Path To the folder; $destination='path/folder/abc.zip'// Path to the file and file name ; $include_dir = false; $archive = 'abc.zip'// File Name ; if (!extension_loaded('zip') || !file_exists($source)) { return false; } if (file_exists($destination)) { unlink ($destination); } $zip = new ZipArchive; if (!$zip->open($archive, ZipArchive::CREATE)) { return false; } $source = str_replace('\\', '/', realpath($source)); if (is_dir($source) === true) { $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); 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)); } $zip->close(); header('Content-Type: application/zip'); header('Content-disposition: attachment; filename='.$archive); header('Content-Length: '.filesize($archive)); readfile($archive); unlink($archive); }
코드 관련 문제가 있으면 알려주십시오.
-
==============================
7.Mac OSX에서이 Zip 기능을 실행해야했습니다.
Mac OSX에서이 Zip 기능을 실행해야했습니다.
그래서 나는 항상 성가신 .z_Store를 압축 할 것입니다.
additionalIgnore 파일을 추가하여 https://stackoverflow.com/users/2019515/user2019515를 수정했습니다.
function zipIt($source, $destination, $include_dir = false, $additionalIgnoreFiles = array()) { // Ignore "." and ".." folders by default $defaultIgnoreFiles = array('.', '..'); // include more files to ignore $ignoreFiles = array_merge($defaultIgnoreFiles, $additionalIgnoreFiles); 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_FIRST); 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); // purposely ignore files that are irrelevant if( in_array(substr($file, strrpos($file, '/')+1), $ignoreFiles) ) 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에서 .DS_Store를 무시하면 실행합니다.
압축 ( '/ 경로 / 그래서 / 폴더', '/ 경로 / to / compressed.zip', falceae, 배열 ( '. Ten_store'));
-
==============================
8.훌륭한 솔루션이지만 내 Windows 용으로 수정해야합니다. 수정 코드 아래
훌륭한 솔루션이지만 내 Windows 용으로 수정해야합니다. 수정 코드 아래
function Zip($source, $destination){ 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 (is_dir($source) === true) { $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); foreach ($files as $file) { $file = str_replace('\\', '/', $file); // Ignore "." and ".." folders if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) ) continue; if (is_dir($file) === true) { $zip->addEmptyDir(str_replace($source . '/', '', $file)); } else if (is_file($file) === true) { $str1 = str_replace($source . '/', '', '/'.$file); $zip->addFromString($str1, file_get_contents($file)); } } } else if (is_file($source) === true) { $zip->addFromString(basename($source), file_get_contents($source)); } return $zip->close(); }
-
==============================
9.이 코드는 Windows와 Linux 모두에서 작동합니다.
이 코드는 Windows와 Linux 모두에서 작동합니다.
function Zip($source, $destination) { if (!extension_loaded('zip') || !file_exists($source)) { return false; } $zip = new ZipArchive(); if (!$zip->open($destination, ZIPARCHIVE::CREATE)) { return false; } if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { DEFINE('DS', DIRECTORY_SEPARATOR); //for windows } else { DEFINE('DS', '/'); //for linux } $source = str_replace('\\', DS, realpath($source)); if (is_dir($source) === true) { $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); echo $source; foreach ($files as $file) { $file = str_replace('\\',DS, $file); // Ignore "." and ".." folders if( in_array(substr($file, strrpos($file, DS)+1), array('.', '..')) ) continue; $file = realpath($file); if (is_dir($file) === true) { $zip->addEmptyDir(str_replace($source . DS, '', $file . DS)); } else if (is_file($file) === true) { $zip->addFromString(str_replace($source . DS, '', $file), file_get_contents($file)); } echo $source; } } else if (is_file($source) === true) { $zip->addFromString(basename($source), file_get_contents($source)); } return $zip->close(); }
-
==============================
10.Alix의 내 버전 기반은 Windows에서 작동하고 잘만하면 * nix에서도 작동합니다.
Alix의 내 버전 기반은 Windows에서 작동하고 잘만하면 * nix에서도 작동합니다.
function addFolderToZip($source, $destination, $flags = ZIPARCHIVE::OVERWRITE) { $source = realpath($source); $destination = realpath($destination); if (!file_exists($source)) { die("file does not exist: " . $source); } $zip = new ZipArchive(); if (!$zip->open($destination, $flags )) { die("Cannot open zip archive: " . $destination); } $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); $sourceWithSeparator = $source . DIRECTORY_SEPARATOR; foreach ($files as $file) { // Ignore "." and ".." folders if(in_array(substr($file,strrpos($file, DIRECTORY_SEPARATOR)+1),array('.', '..'))) continue; if (is_dir($file) === true) { $zip->addEmptyDir( str_replace($sourceWithSeparator, '', $file . DIRECTORY_SEPARATOR)); } else if (is_file($file) === true) { $zip->addFile($file, str_replace($sourceWithSeparator, '', $file)); } } return $zip->close(); }
-
==============================
11.다음은 읽기 쉽고 재귀 적으로 사용하기 쉬운 함수입니다.
다음은 읽기 쉽고 재귀 적으로 사용하기 쉬운 함수입니다.
function zip_r($from, $zip, $base=false) { if (!file_exists($from) OR !extension_loaded('zip')) {return false;} if (!$base) {$base = $from;} $base = trim($base, '/'); $zip->addEmptyDir($base); $dir = opendir($from); while (false !== ($file = readdir($dir))) { if ($file == '.' OR $file == '..') {continue;} if (is_dir($from . '/' . $file)) { zip_r($from . '/' . $file, $zip, $base . '/' . $file); } else { $zip->addFile($from . '/' . $file, $base . '/' . $file); } } return $zip; } $from = "/path/to/folder"; $base = "basezipfolder"; $zip = new ZipArchive(); $zip->open('zipfile.zip', ZIPARCHIVE::CREATE); $zip = zip_r($from, $zip, $base); $zip->close();
from https://stackoverflow.com/questions/1334613/how-to-recursively-zip-a-directory-in-php by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
PHP 작업을 비동기 적으로 실행하십시오. (0) | 2018.09.11 |
---|---|
PHP / MySQL은 행을 삽입 한 다음 'id'를 얻습니다. (0) | 2018.09.11 |
PHP에서 사용자를위한 CSV 파일 만들기 (0) | 2018.09.11 |
PHP를위한 최고의 IDE 란 무엇입니까? [닫은] (0) | 2018.09.11 |
준비된 진술은 언제 사용해야합니까? (0) | 2018.09.11 |