PHP 日本會議 2024

Zip 函式

警告

自 PHP 8.0.0 起,程序式 API 已被棄用。ZipArchive 應該改為使用。

目錄

新增註解

使用者貢獻的註解 20 則註解

14
nielsvandenberge at hotmail dot com
17 年前
這是我用來解壓縮檔案的函式。
它包含下列選項
* 解壓縮到您喜歡的任何目錄
* 解壓縮到 zip 檔案的目錄
* 解壓縮到與 zip 檔案名稱相同的目錄(位於 zip 檔案的目錄中)。(例如:C:\test.zip 將解壓縮到 C:\test\)
* 是否覆寫現有檔案
* 它會使用函式 Create_dirs($path) 建立不存在的目錄

您應該使用帶有斜線 (/) 的絕對路徑,而不是反斜線 (\)。
我使用 PHP 5.2.0 和載入的 php_zip.dll 擴充功能測試過。

<?php
/**
* 解壓縮來源檔案到目標目錄
*
* @param string ZIP 檔案的路徑。
* @param string ZIP 檔案應該解壓縮到的路徑,如果為 false,則使用 ZIP 檔案的目錄
* @param boolean 指示是否將檔案解壓縮到以 ZIP 檔案名稱命名的目錄中(true),否則不解壓縮到該目錄(false)(僅當目標目錄設定為 false 時!)
* @param boolean 覆寫現有檔案(true)或不覆寫(false)
*
* @return boolean 成功或失敗
*/
function unzip($src_file, $dest_dir=false, $create_zip_name_dir=true, $overwrite=true)
{
if (
$zip = zip_open($src_file))
{
if (
$zip)
{
$splitter = ($create_zip_name_dir === true) ? "." : "/";
if (
$dest_dir === false) $dest_dir = substr($src_file, 0, strrpos($src_file, $splitter))."/";

// 建立目標目錄的目錄,如果它們還不存在
create_dirs($dest_dir);

// 針對 zip 封包中的每個檔案
while ($zip_entry = zip_read($zip))
{
// 現在我們要建立目標目錄中的目錄

// 如果檔案不在根目錄中
$pos_last_slash = strrpos(zip_entry_name($zip_entry), "/");
if (
$pos_last_slash !== false)
{
// 建立應該儲存 zip 條目的目錄(結尾帶有 "/")
create_dirs($dest_dir.substr(zip_entry_name($zip_entry), 0, $pos_last_slash+1));
}

// 開啟條目
if (zip_entry_open($zip,$zip_entry,"r"))
{

// 要儲存到磁碟上的檔案名稱
$file_name = $dest_dir.zip_entry_name($zip_entry);

// 檢查是否應該覆寫檔案
if ($overwrite === true || $overwrite === false && !is_file($file_name))
{
// 取得 zip 條目的內容
$fstream = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));

file_put_contents($file_name, $fstream );
// 設定權限
chmod($file_name, 0777);
echo
"save: ".$file_name."<br />";
}

// 關閉條目
zip_entry_close($zip_entry);
}
}
// 關閉 zip 檔案
zip_close($zip);
}
}
else
{
return
false;
}

return
true;
}

/**
* 如果目錄不存在,此函數會遞迴建立目錄
*
* @param String 應該建立的路徑
*
* @return void
*/
function create_dirs($path)
{
if (!
is_dir($path))
{
$directory_path = "";
$directories = explode("/",$path);
array_pop($directories);

foreach(
$directories as $directory)
{
$directory_path .= $directory."/";
if (!
is_dir($directory_path))
{
mkdir($directory_path);
chmod($directory_path, 0777);
}
}
}
}

// 將 C:/zipfiletest/zip-file.zip 解壓縮到 C:/zipfiletest/zip-file/ 並覆寫現有檔案
unzip("C:/zipfiletest/zip-file.zip", false, true, true);

// 將 C:/zipfiletest/zip-file.zip 解壓縮到 C:/another_map/zipfiletest/ 且不覆寫現有檔案。注意:它不會建立一個以 zip 檔案名稱命名的資料夾!
unzip("C:/zipfiletest/zip-file.zip", "C:/another_map/zipfiletest/", true, false);

?>
5
yarms at mail dot ru
15 年前
用於解壓縮具有資料夾結構的檔案的非常簡短的函數版本
<?php

function unzip($file){

$zip=zip_open(realpath(".")."/".$file);
if(!
$zip) {return("無法處理檔案 '{$file}'");}

$e='';

while(
$zip_entry=zip_read($zip)) {
$zdir=dirname(zip_entry_name($zip_entry));
$zname=zip_entry_name($zip_entry);

if(!
zip_entry_open($zip,$zip_entry,"r")) {$e.="無法處理檔案 '{$zname}'";continue;}
if(!
is_dir($zdir)) mkdirr($zdir,0777);

#print "{$zdir} | {$zname} \n";

$zip_fs=zip_entry_filesize($zip_entry);
if(empty(
$zip_fs)) continue;

$zz=zip_entry_read($zip_entry,$zip_fs);

$z=fopen($zname,"w");
fwrite($z,$zz);
fclose($z);
zip_entry_close($zip_entry);

}
zip_close($zip);

return(
$e);
}

function
mkdirr($pn,$mode=null) {

if(
is_dir($pn)||empty($pn)) return true;
$pn=str_replace(array('/', ''),DIRECTORY_SEPARATOR,$pn);

if(
is_file($pn)) {trigger_error('mkdirr() 檔案已存在', E_USER_WARNING);return false;}

$next_pathname=substr($pn,0,strrpos($pn,DIRECTORY_SEPARATOR));
if(
mkdirr($next_pathname,$mode)) {if(!file_exists($pn)) {return mkdir($pn,$mode);} }
return
false;
}

unzip("test.zip");

?>

祝您有美好的一天 :)
2
nheimann at gmx dot net
17 年前
使用此擴充功能,您可以使用 ZipArchive 物件新增帶有檔案的資料夾

<?php
/**
* FlxZipArchive,繼承自 ZipArchiv。
* 加入包含檔案和子目錄的目錄。
*
* <code>
* $archive = new FlxZipArchive;
* // .....
* $archive->addDir( 'test/blub', 'blub' );
* </code>
*/
class FlxZipArchive extends ZipArchive {
/**
* 將包含檔案和子目錄的目錄加入到壓縮檔中
*
* @param string $location 實際路徑
* @param string $name 在壓縮檔中的名稱
* @author Nicolas Heimann
* @access private
**/

public function addDir($location, $name) {
$this->addEmptyDir($name);

$this->addDirDo($location, $name);
// } // EO addDir;

/**
* 將檔案和目錄加入到壓縮檔中。
*
* @param string $location 實際路徑
* @param string $name 在壓縮檔中的名稱
* @author Nicolas Heimann
* @access private
**/

private function addDirDo($location, $name) {
$name .= '/';
$location .= '/';

// 讀取目錄中的所有檔案
$dir = opendir ($location);
while (
$file = readdir($dir))
{
if (
$file == '.' || $file == '..') continue;

// 遞迴,如果是目錄:FlxZipArchive::addDir(),否則 ::File();
$do = (filetype() == 'dir') ? 'addDir' : 'addFile';
$this->$do($location . $file, $name . $file);
}
}
// EO addDirDo();
}
?>
1
Anonymous
19 年前
如果您(像我一樣)只是想將一個大的字串(例如,序列化的陣列之類)儲存在 mysql BLOB 欄位中,請記住 mysql 有一對 COMPRESS() 和 UNCOMPRESS() 函數可以做到這一點。因此,當從 Java 等其他語言存取資料庫時,也可以進行壓縮/解壓縮。
1
wdtemp at seznam dot cz
14 年前
您好,
如果您只有 ZIP 檔案的原始內容字串,而且由於安全模式的限制,您無法在伺服器上建立檔案,以便將檔案傳遞給 zip_open(),那麼您將很難取得 ZIP 資料的解壓縮內容。
這可能會有所幫助
我寫了一個簡單的 ZIP 解壓縮函式,用於解壓縮儲存在字串中的壓縮檔中的第一個檔案(無論它是什麼檔案)。它只是解析第一個檔案的本地檔案標頭,取得該檔案的原始壓縮資料,然後解壓縮該資料(通常,ZIP 檔案中的資料使用 'DEFLATE' 方法壓縮,因此我們將使用 gzinflate() 函式解壓縮它)。

<?php
function decompress_first_file_from_zip($ZIPContentStr){
//輸入:ZIP 壓縮檔 - 整個 ZIP 壓縮檔的內容,以字串形式表示
//輸出:ZIP 壓縮檔中第一個封裝檔案的解壓縮內容
//讓我們解析 ZIP 壓縮檔
//(詳情請參閱 'http://en.wikipedia.org/wiki/ZIP_%28file_format%29')
//解析 ZIP 壓縮檔中第一個檔案條目的「本地檔案標頭」
if(strlen($ZIPContentStr)<102){
//任何小於 102 位元組的 ZIP 檔案都是無效的
printf("錯誤:輸入資料太短<br />\n");
return
'';
}
$CompressedSize=binstrtonum(substr($ZIPContentStr,18,4));
$UncompressedSize=binstrtonum(substr($ZIPContentStr,22,4));
$FileNameLen=binstrtonum(substr($ZIPContentStr,26,2));
$ExtraFieldLen=binstrtonum(substr($ZIPContentStr,28,2));
$Offs=30+$FileNameLen+$ExtraFieldLen;
$ZIPData=substr($ZIPContentStr,$Offs,$CompressedSize);
$Data=gzinflate($ZIPData);
if(
strlen($Data)!=$UncompressedSize){
printf("錯誤:解壓縮資料的大小錯誤<br />\n");
return
'';
}
else return
$Data;
}

function
binstrtonum($Str){
//傳回以字串形式傳遞的原始二進位資料表示的數字。
//例如,當我們只將檔案的內容儲存在字串中時,從檔案中讀取整數時,此函式非常有用。
//範例:
// chr(0xFF) 將產生 255
// chr(0xFF).chr(0xFF).chr(0x00).chr(0x00) 將產生 65535
// chr(0xFF).chr(0xFF).chr(0xFF).chr(0x00) 將產生 16777215
$Num=0;
for(
$TC1=strlen($Str)-1;$TC1>=0;$TC1--){ //從最高有效位元組開始
$Num<<=8; //向左移動一個位元組(8 位元)
$Num|=ord($Str[$TC1]); //加入新的位元組
}
return
$Num;
}
?>

請享用!!!
wdim
2
bushj at rpi dot edu
17 年前
我建立了一個 zip 串流處理常式,以防您的發行版本未使用新的 ZipArchive 系統內建的處理常式。這個處理常式還具有按索引和名稱取得條目的功能。它的功能與內建的 gzip/bzip2 壓縮串流處理常式類似(http://us2.php.net/manual/en/wrappers.compression.php),只是它不支援寫入。

使用方法
fopen('zip://absolute/path/to/file.zip?entryname', $mode) 或
fopen('zip://absolute/path/to/file.zip#entryindex', $mode) 或
fopen('zip://absolute/path/to/file.zip', $mode)

$mode 只能是 'r' 或 'rb'。在最後一種情況下,會使用 zip 檔案中的第一個條目。

<?php
class ZipStream {
public
$zip; // zip 檔案
public $entry; // 已開啟的 zip 條目
public $length; // zip 條目未壓縮的大小
public $position; // zip 條目讀取時的當前位置
// 開啟 zip 檔案,然後檢索並開啟要串流的條目
public function stream_open($path, $mode, $options, &$opened_path) {
if (
$mode != 'r' && $mode != 'rb') // 只接受 r 和 rb 模式,不寫入!
return false;
$path = 'file:///'.substr($path, 6); // 將 file:/// 替換為 zip://,以便我們可以使用 url_parse
$url = parse_url($path);
// 開啟 zip 檔案
$filename = $url['path'];
$this->zip = zip_open($filename);
if (!
is_resource($this->zip))
return
false;

// 如果給定條目名稱,則尋找該條目
if (array_key_exists('query', $url) && $url['query']) {
$path = $url['query'];
do {
$this->entry = zip_read($this->zip);
if (!
is_resource($this->entry))
return
false;
} while (
zip_entry_name($this->entry) != $path);
} else {
// 否則依索引取得 (預設為 0)
$id = 0;
if (
array_key_exists('fragment', $url) && is_int($url['fragment']))
$id = $url['fragment']*1;
for (
$i = 0; $i <= $id; $i++) {
$this->entry = zip_read($this->zip);
if (!
is_resource($this->entry))
return
false;
}
}
// 設定長度並開啟條目進行讀取
$this->length = zip_entry_filesize($this->entry);
$this->position = 0;
zip_entry_open($this->zip, $this->entry, $mode);
return
true;
}
// 關閉 zip 條目和檔案
public function stream_close() { @zip_entry_close($this->entry); @zip_close($this->zip); }
// 傳回從 zip 條目讀取了多少位元組
public function stream_tell() { return $this->position; }
// 傳回是否已到達 zip 條目的末尾
public function stream_eof() { return $this->position >= $this->length; }
// 傳回 stat 陣列,只有 'size' 填入未壓縮的 zip 條目大小
public function url_stat() { return array('dev'=>0, 'ino'=>0, 'mode'=>0, 'nlink'=>0, 'uid'=>0, 'gid'=>0, 'rdev'=>0, 'size'=>$this->length, 'atime'=>0, 'mtime'=>0, 'ctime'=>0, 'blksize'=>0, 'blocks'=>0); }
// 讀取下一個 $count 位元組或直到 zip 條目的末尾。傳回資料,如果沒有讀取到資料,則傳回 false。
public function stream_read($count) {
$this->position += $count;
if (
$this->position > $this->length)
$this->position = $this->length;
return
zip_entry_read($this->entry, $count);
}
}
// 註冊 zip 串流處理器
stream_wrapper_register('zip', 'ZipStream'); // 如果失敗,則表示已經有 zip 串流處理器,我們將只使用該處理器
?>
0
vk.com/vknkk
9 年前
<?php
// 將所有 *.zip 檔案 (包括子資料夾) 解壓縮到目前目錄 (在 Win7 上開發並測試)
$files = glob('*.zip');
if (
$files)
foreach (
$files as $fl) {
$zip = zip_open($fl);
if (
is_resource($zip)) {
$dir = substr($fl, 0, -4); // 以 *.zip 檔案名稱命名目錄 (解壓縮到 "*/")
if (!is_dir($dir))
mkdir($dir);
while (
is_resource($entry = zip_read($zip))) {
$is_file = true;
$name = zip_entry_name($entry);
$name_parts = explode('/', $name);
if (
count($name_parts) > 1) { // 處理子資料夾
$path = array_pop($name_parts);
$is_file = !empty($path);
$path = $dir;
foreach (
$name_parts as $part) {
$path .= '/'.$part;
if (!
is_dir($path))
mkdir($path);
}
}
if (
$is_file)
file_put_contents($dir.'/'.$name, zip_entry_read($entry, zip_entry_filesize($entry)));
}
zip_close($zip);
}
}
1
chris
21 年前
如果您使用 zip 函數將封存檔解壓縮到實際檔案,請注意包含子資料夾的封存檔。假設您嘗試從封存檔中解壓縮 foldername/filename.txt。您無法 fopen 一個不存在的目錄,因此您必須檢查目錄 foldername 是否存在,如果找不到則建立它,然後 fopen foldername/filename.txt 並開始寫入。
0
rodrigo dot moraes at gmail dot com
16 年前
這是一個更簡單的擴展類別,可以遞迴新增整個目錄,並保持相同的結構。它使用 SPL。

<?php
class MyZipArchive extends ZipArchive
{
/**
*
* 遞迴新增目錄。
*
* @param string $filename 要新增的檔案路徑。
*
* @param string $localname ZIP 封存檔內的本機名稱。
*
*/
public function addDir($filename, $localname)
{
$this->addEmptyDir($localname);
$iter = new RecursiveDirectoryIterator($filename, FilesystemIterator::SKIP_DOTS);

foreach (
$iter as $fileinfo) {
if (!
$fileinfo->isFile() && !$fileinfo->isDir()) {
continue;
}

$method = $fileinfo->isFile() ? 'addFile' : 'addDir';
$this->$method($fileinfo->getPathname(), $localname . '/' .
$fileinfo->getFilename());
}
}
}
?>

[danbrown AT php DOT net 編輯:包含 (bart AT blueberry DOT nl) 於 2011 年 6 月 29 日建議的錯誤修復,訊息如下:「修正無限迭代器,新增 FilesystemIterator::SKIP_DOTS 旗標」]
0
jeswanth@gmail
17 年前
大家好,

下面有很多提取檔案的函數,但它們缺少的是設定檔案權限。在某些伺服器上,檔案權限非常重要,而且在建立第一個目錄後,指令碼就會停止工作。因此,我在程式碼中新增了 chmod。程式碼只有一個限制,沒有副檔名的檔案不會被視為檔案或目錄,因此它們不會被 chmod,無論如何這不會影響程式碼。希望這有幫助。

<?php
function unpackZip($dir,$file) {
if (
$zip = zip_open($dir.$file.".zip")) {
if (
$zip) {
mkdir($dir.$file);
chmod($dir.$file, 0777);
while (
$zip_entry = zip_read($zip)) {
if (
zip_entry_open($zip,$zip_entry,"r")) {
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
$dir_name = dirname(zip_entry_name($zip_entry));
if (
$dir_name != ".") {
$dir_op = $dir.$file."/";
foreach (
explode("/",$dir_name) as $k) {
$dir_op = $dir_op . $k;
if (
is_file($dir_op)) unlink($dir_op);
if (!
is_dir($dir_op)) mkdir($dir_op);
chmod($dir_op, 0777);
$dir_op = $dir_op . "/" ;
}
}
$fp=fopen($dir.$file."/".zip_entry_name($zip_entry),"w+");
chmod($dir.$file."/".zip_entry_name($zip_entry), 0777);
fwrite($fp,$buf);

fclose($fp);

zip_entry_close($zip_entry);
} else
return
false;
}
zip_close($zip);
}
} else
return
false;

return
true;
}

$dir = $_SERVER['DOCUMENT_ROOT']."/"."destdirectory/";
$file = 'zipfilename_without_extension';
unpackZip($dir,$file);
$print = $_SERVER['DOCUMENT_ROOT'];
?>
0
bholub at chiefprojects dot com
18 年前
這會簡單地將 $zip 解壓縮(包含目錄)到 $dir -- 在此範例中,zip 檔案正在上傳。
<?php
$dir
= 'C:\\reports-temp\\';
$zip = zip_open($_FILES['report_zip']['tmp_name']);
while(
$zip_entry = zip_read($zip)) {
$entry = zip_entry_open($zip,$zip_entry);
$filename = zip_entry_name($zip_entry);
$target_dir = $dir.substr($filename,0,strrpos($filename,'/'));
$filesize = zip_entry_filesize($zip_entry);
if (
is_dir($target_dir) || mkdir($target_dir)) {
if (
$filesize > 0) {
$contents = zip_entry_read($zip_entry, $filesize);
file_put_contents($dir.$filename,$contents);
}
}
}
?>
0
angelnsn1 at hotmail dot com
18 年前
此函式會解壓縮所有檔案和子目錄,您可以選擇詳細模式以取得已解壓縮檔案的路徑。此函式會回傳一個訊息,指出是否有錯誤,如果訊息為 OK,則表示所有動作都已完成。

---

程式碼

<?php
function unzip($dir, $file, $verbose = 0) {

$dir_path = "$dir$file";
$zip_path = "$dir$file.zip";

$ERROR_MSGS[0] = "OK";
$ERROR_MSGS[1] = "Zip 路徑 $zip_path 不存在。";
$ERROR_MSGS[2] = "用於解壓縮檔案的目錄 $dir_path 已存在,無法繼續。";
$ERROR_MSGS[3] = "開啟 $zip_path 檔案時發生錯誤。";

$ERROR = 0;

if (
file_exists($zip_path)) {

if (!
file_exists($dir_path)) {

mkdir($dir_path);

if ((
$link = zip_open($zip_path))) {

while ((
$zip_entry = zip_read($link)) && (!$ERROR)) {

if (
zip_entry_open($link, $zip_entry, "r")) {

$data = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
$dir_name = dirname(zip_entry_name($zip_entry));
$name = zip_entry_name($zip_entry);

if (
$name[strlen($name)-1] == '/') {

$base = "$dir_path/";

foreach (
explode("/", $name) as $k) {

$base .= "$k/";

if (!
file_exists($base))
mkdir($base);

}

}
else {

$name = "$dir_path/$name";

if (
$verbose)
echo
"正在解壓縮: $name<br>";

$stream = fopen($name, "w");
fwrite($stream, $data);

}

zip_entry_close($zip_entry);

}
else
$ERROR = 4;

}

zip_close($link);

}
else
$ERROR = "3";
}
else
$ERROR = 2;
}
else
$ERROR = 1;

return
$ERROR_MSGS[$ERROR];

}
?>

---

範例

<?php
$error
= unzip("d:/www/dir/", "zipname", 1);

echo
$error;
?>

---

希望這對您有幫助,
再見。
0
ringu at mail dot ru
19 年前
我嘗試尋找一個函式來顯示 zip 封存檔中是否存在檔案。當然,我沒有找到,所以自己寫了一個。

首先,只會檢查封存檔中的檔案列表,如果找不到所有檔案,函式會回傳 FALSE。

<?php
function zipx_entries_exists()
{
$names=array();
$args=func_get_args();
$far_size=count($args);
if(
$args[0])
{
for(;
$zip_entry=zip_read($args[0]); $names[]= zip_entry_name($zip_entry));
for(
$x=1; $x<=$far_size; $t+=in_array($args[$x], $names), $x++);
return
$t==--$far_size;
}else{
return
'描述子中沒有 zip 檔案!';
}
}

範例:
$zip=zip_open('any_zip_file_zip');
var_dump(zip_entries_exists($zip, 'photo_1.jpg', 'photo_2.jpg'));

第二個函式會嘗試在 zip 中尋找檔案,如果找不到,會回傳字串,其中包含以指定分隔符號分隔的未找到檔案名稱:

function
zipx_entries_nonexists_list()
{
$names=array();
$args=func_get_args();
$m=NULL;
$far_size=count($args);
if(
$args[0])
{
for(;
$zip_entry=zip_read($args[0]); $names[]= zip_entry_name($zip_entry));
for(
$x=2; $x<=$far_size; $m.=(in_array($args[$x], $names) ? NULL : $args[$x].$args[1]), $x++);
return
trim($m, $args[1]);
}else{
return
'描述子中沒有 zip 檔案!';
}
}
?>

範例
<?php
$zip
=zip_open('any_zip_file_zip');
var_dump(zip_entries_nonexists_list($zip, '<br />', 'photo_1.jpg', 'photo_2.jpg'));
?>

如果找不到檔案,它會回傳
photo_1.jpg<br />photo_2.jpg
0
krishnendu at spymac dot com
20 年前
如果您想使用 php 解壓縮受密碼保護的檔案,請嘗試以下命令......它在 Unix/Apache 環境中運作......我尚未在任何其他環境中測試過......

system("`which unzip` -P Password $zipfile -d $des",$ret_val)

其中 $zipfile 是要解壓縮的 .zip 檔案路徑,$des 是目標目錄的路徑......此處可以使用此系統命令的腳本的絕對和相對路徑......

如果一切運作良好......檔案應解壓縮到 $des 目錄中,並且 $ret_val 的值將為 0,表示成功 (info-zip.org)

此致
Krishnendu
0
travis
21 年前
只是提醒一下——使用前面提到的動態 zip 類似乎會導致高位 ASCII 字元出現問題(它們的值未正確保留,且檔案無法解壓縮)
-1
phillpafford+php at gmail dot com
16 年前
你其實可以直接使用 Linux 指令

<?php

// 取得日期
$date = date("m-d-y");

// 建立 Zip 檔名
$zipname = "archive/site-script-backup." . $date . ".zip";

// 建立 zip 壓縮檔
$cmd = `zip -r $zipname *`;

?>
-1
shadowbranch at gmail dot com
13 年前
這是一個最簡單的解壓縮檔案的方法。將你的檔名傳遞給這個函式,它會將檔案解壓縮到腳本的目前目錄,並在 Unix 類型的作業系統上正確設定權限。這方法更容易理解和閱讀。

<?php
function unzip($file){
$zip = zip_open($file);
if(
is_resource($zip)){
$tree = "";
while((
$zip_entry = zip_read($zip)) !== false){
echo
"正在解壓縮 ".zip_entry_name($zip_entry)."\n";
if(
strpos(zip_entry_name($zip_entry), DIRECTORY_SEPARATOR) !== false){
$last = strrpos(zip_entry_name($zip_entry), DIRECTORY_SEPARATOR);
$dir = substr(zip_entry_name($zip_entry), 0, $last);
$file = substr(zip_entry_name($zip_entry), strrpos(zip_entry_name($zip_entry), DIRECTORY_SEPARATOR)+1);
if(!
is_dir($dir)){
@
mkdir($dir, 0755, true) or die("無法建立 $dir\n");
}
if(
strlen(trim($file)) > 0){
$return = @file_put_contents($dir."/".$file, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)));
if(
$return === false){
die(
"無法寫入檔案 $dir/$file\n");
}
}
}else{
file_put_contents($file, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)));
}
}
}else{
echo
"無法開啟 zip 檔案\n";
}
}
?>
-1
mmj48 at gmail dot com
17 年前
這是我寫的一個函式,它會解壓縮 zip 檔案並保留相同的目錄結構...

請享用

<?php
function unzip($zipfile)
{
$zip = zip_open($zipfile);
while (
$zip_entry = zip_read($zip)) {
zip_entry_open($zip, $zip_entry);
if (
substr(zip_entry_name($zip_entry), -1) == '/') {
$zdir = substr(zip_entry_name($zip_entry), 0, -1);
if (
file_exists($zdir)) {
trigger_error('目錄 "<b>' . $zdir . '</b>" 已存在', E_USER_ERROR);
return
false;
}
mkdir($zdir);
}
else {
$name = zip_entry_name($zip_entry);
if (
file_exists($name)) {
trigger_error('檔案 "<b>' . $name . '</b>" 已存在', E_USER_ERROR);
return
false;
}
$fopen = fopen($name, "w");
fwrite($fopen, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)), zip_entry_filesize($zip_entry));
}
zip_entry_close($zip_entry);
}
zip_close($zip);
return
true;
}
?>
-1
tom
19 年前
如果你只是想解壓縮 zip 資料夾,以下是一些較為精簡的函式替代方案:

<?php

function unzip($zip_file, $src_dir, $extract_dir)
{
copy($src_dir . "/" . $zip_file, $extract_dir . "/" . $zip_file);
chdir($extract_dir);
shell_exec("unzip $zip_file");
}

?>

你不需要 ZIP 擴充功能來執行此操作。
-2
candido1212 at yahoo dot com dot br
19 年前
新的 Unzip 函式,遞迴解壓縮
需要 mkdirr() (遞迴建立目錄)

<?php
$file
= "2537c61ef7f47fc3ae919da08bcc1911.zip";
$dir = getcwd();
function
Unzip($dir, $file, $destiny="")
{
$dir .= DIRECTORY_SEPARATOR;
$path_file = $dir . $file;
$zip = zip_open($path_file);
$_tmp = array();
$count=0;
if (
$zip)
{
while (
$zip_entry = zip_read($zip))
{
$_tmp[$count]["filename"] = zip_entry_name($zip_entry);
$_tmp[$count]["stored_filename"] = zip_entry_name($zip_entry);
$_tmp[$count]["size"] = zip_entry_filesize($zip_entry);
$_tmp[$count]["compressed_size"] = zip_entry_compressedsize($zip_entry);
$_tmp[$count]["mtime"] = "";
$_tmp[$count]["comment"] = "";
$_tmp[$count]["folder"] = dirname(zip_entry_name($zip_entry));
$_tmp[$count]["index"] = $count;
$_tmp[$count]["status"] = "ok";
$_tmp[$count]["method"] = zip_entry_compressionmethod($zip_entry);

if (
zip_entry_open($zip, $zip_entry, "r"))
{
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
if(
$destiny)
{
$path_file = str_replace("/",DIRECTORY_SEPARATOR, $destiny . zip_entry_name($zip_entry));
}
else
{
$path_file = str_replace("/",DIRECTORY_SEPARATOR, $dir . zip_entry_name($zip_entry));
}
$new_dir = dirname($path_file);

// Create Recursive Directory
mkdirr($new_dir);


$fp = fopen($dir . zip_entry_name($zip_entry), "w");
fwrite($fp, $buf);
fclose($fp);

zip_entry_close($zip_entry);
}
echo
"\n</pre>";
$count++;
}

zip_close($zip);
}
}
Unzip($dir,$file);
?>
To Top