PHP Conference Japan 2024

ZipArchive::addEmptyDir

(PHP 5 >= 5.2.0,PHP 7,PHP 8,PECL zip >= 1.8.0)

ZipArchive::addEmptyDir新增一個新的目錄

描述

public ZipArchive::addEmptyDir(string $dirname, int $flags = 0): bool

在封存檔中新增一個空目錄。

參數

dirname

要新增的目錄。

flags

ZipArchive::FL_ENC_GUESSZipArchive::FL_ENC_UTF_8ZipArchive::FL_ENC_CP437 組成的位元遮罩。這些常數的行為在 ZIP 常數頁面中有描述。

回傳值

成功時回傳 true,失敗時回傳 false

更新日誌

版本 描述
8.0.0,PECL zip 1.18.0 新增 flags

範例

範例 1 在封存檔中建立新目錄

<?php
$zip
= new ZipArchive;
if (
$zip->open('test.zip') === TRUE) {
if(
$zip->addEmptyDir('newDirectory')) {
echo
'建立一個新的根目錄';
} else {
echo
'無法建立目錄';
}
$zip->close();
} else {
echo
'失敗';
}
?>
新增註解

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

4
hunter666 at abv dot bg
14 年前
將資料夾和子目錄新增到 zip 封存檔。

<?php
$archive_name
= "archive.zip"; // zip 檔案名稱
$archive_folder = "folder"; // 你要封存的資料夾

$zip = new ZipArchive;
if (
$zip -> open($archive_name, ZipArchive::CREATE) === TRUE)
{
$dir = preg_replace('/[\/]{2,}/', '/', $archive_folder."/");

$dirs = array($dir);
while (
count($dirs))
{
$dir = current($dirs);
$zip -> addEmptyDir($dir);

$dh = opendir($dir);
while(
$file = readdir($dh))
{
if (
$file != '.' && $file != '..')
{
if (
is_file($file))
$zip -> addFile($dir.$file, $dir.$file);
elseif (
is_dir($file))
$dirs[] = $dir.$file."/";
}
}
closedir($dh);
array_shift($dirs);
}

$zip -> close();
echo
'封存成功!';
}
else
{
echo
'錯誤,無法建立 zip 檔案!';
}
?>
1
thomas dot rubbert at yahoo dot de
15 年前
這是一個基於堆疊來壓縮目錄的方法。沒有遞迴,沒有函式,沒有類別

<?php
$zip
= new ZipArchive();
$zip->open('test.zip', ZipArchive::CREATE);

$dirName = 'test';

if (!
is_dir($dirName)) {
throw new
Exception('Directory ' . $dirName . ' does not exist');
}

$dirName = realpath($dirName);
if (
substr($dirName, -1) != '/') {
$dirName.= '/';
}

/*
* NOTE BY danbrown AT php DOT net: A good method of making
* portable code in this case would be usage of the PHP constant
* DIRECTORY_SEPARATOR in place of the '/' (forward slash) above.
*/

$dirStack = array($dirName);
//Find the index where the last dir starts
$cutFrom = strrpos(substr($dirName, 0, -1), '/')+1;

while (!empty(
$dirStack)) {
$currentDir = array_pop($dirStack);
$filesToAdd = array();

$dir = dir($currentDir);
while (
false !== ($node = $dir->read())) {
if ((
$node == '..') || ($node == '.')) {
continue;
}
if (
is_dir($currentDir . $node)) {
array_push($dirStack, $currentDir . $node . '/');
}
if (
is_file($currentDir . $node)) {
$filesToAdd[] = $node;
}
}

$localDir = substr($currentDir, $cutFrom);
$zip->addEmptyDir($localDir);

foreach (
$filesToAdd as $file) {
$zip->addFile($currentDir . $file, $localDir . $file);
}
}

$zip->close();
?>
1
lea dot gris at noiraude dot net
7 個月前
addEmptyDir 方法不處理權限位元和目錄的 mtime。這些需要在 Zip 壓縮檔中建立目錄後單獨設定。

請注意,只有 PHP >= 8.0 才可設定 mtime,因此在 PHP 7.4 及更低版本中,它會保持 addEmptyDir 呼叫時的目前時間戳記。

以下是一個函式,用於修正 Zip 壓縮檔中目錄的權限和 mtime

<pre><code lang="php">
function fixDirAttributes(ZipArchive $zip, string $path, string $name)
{
// 取得 Zip 壓縮檔中目錄的索引
$indexInZip = $zip->locateName('/' === mb_substr($name, -1) ? $name : $name . '/');
if (false !== $indexInZip) { // 找到名稱
if (method_exists($zip, 'setMtimeIndex')) { // PHP >= 8.0.0, PECL zip >= 1.16.0
$zip->setMtimeIndex($indexInZip, filemtime($path)); // 修正目錄的 mtime
}
$filePerms = fileperms($path); // 取得目錄的權限
if (false !== $filePerms) { // 支援 filePerms
$attr = $filePerms << 16; // 將權限左移以取得外部屬性值
$zip->setExternalAttributesIndex($indexInZip, \ZipArchive::OPSYS_UNIX, $attr);
}
}
}
</pre></code>
0
iunknownvb at gmail dot com
1 年前
我稍微修改了 thomas dot rubbert at yahoo dot de 的程式碼

$uploads_dir =storage_path().'/app/public/files/' ;
if(!file_exists($uploads_dir)){
mkdir($uploads_dir,0777,true);
}
$zip_file=$uploads_dir.'download.zip';
if(file_exists($zip_file)){
unlink($zip_file);
}
$zip = new \ZipArchive();
if (!$zip->open($zip_file, \ZIPARCHIVE::CREATE)) {
http_response_code(501);
echo 'Zip 建立失敗';
die();
}
$img=$uploads_dir.'img';

$dirName = realpath($img);
if (substr($dirName, -1) != DIRECTORY_SEPARATOR) {
$dirName.= DIRECTORY_SEPARATOR;
}
$dirStack = array($dirName);
// 找出最後一個目錄開始的索引
$cutFrom = strrpos(substr($dirName, 0, -1), DIRECTORY_SEPARATOR)+1;
while (!empty($dirStack)) {
$currentDir = array_pop($dirStack);
$filesToAdd = array();
$dir = dir($currentDir);
while (false !== ($node = $dir->read())) {
if (($node == '..') || ($node == '.')) {
continue;
}
if (is_dir($currentDir . $node)) {
array_push($dirStack, $currentDir . $node . DIRECTORY_SEPARATOR);
}
if (is_file($currentDir . $node)) {
$filesToAdd[] = $node;
}
}
$localDir =str_replace(DIRECTORY_SEPARATOR,'/',substr($currentDir, $cutFrom));
$zip->addEmptyDir($localDir);
foreach ($filesToAdd as $file) {
$zip->addFile($currentDir . $file, $localDir . $file);
}
}
// 任何其他檔案
$db=$uploads_dir.'databse.db';
//$zip->addFromString(basename($db), file_get_contents($db));
$zip->addFile($db, basename($db));
$zip->close();
0
pagetronic
16 年前
addEmptyDir 現在不存在了,
請使用 $zip->addFile($file, $dir.$fichier);

網路上沒有相關資訊,

addEmptyDir 在 Ubuntu 上運作,但在 Debian Etch 上則無法運作
0
benjamin dot seiller at antwerpes dot de
16 年前
此方法中存在一種錯誤
ZipArchive::addFile
會影響以下的 ZipFolder 類別。
它與作業系統的最大檔案控制代碼數量有關。

作為解決方法,請將檔案計數器新增到類別中,並在達到特定數量的檔案 (目錄也算檔案!) 時關閉並重新開啟壓縮檔。

如需更多詳細資訊,請參閱此處
http://de.php.net/manual/en/function.ziparchive-addfile.php
或直接前往此處
http://bugs.php.net/bug.php?id=40494
或此處
http://pecl.php.net/bugs/bug.php?id=9443
-1
tahazit dot co dot il at gmail dot com
10 年前
在 PHP > 5.4 上,此函式會建立檔案,而不是目錄。

例如

$zip->addEmptyDir ( 'path/to/dir/' );

會建立資料夾「path/」和「path/to/」,以及在後者中建立名為「dir」的虛擬 0 位元組檔案。
如果我們然後將檔案新增到該目錄,例如像這樣

$zip->addFromString ( 'path/to/dir/file.txt', $data );

結果會是在虛擬「dir」檔案旁邊建立一個名為「dir」的獨立資料夾。「dir」資料夾將包含檔案「file.txt」。

這是在使用 PHP 5.4 的 APACHE 伺服器上測試的
-2
D.Jann
16 年前
我對 dayjo 的程式碼做了一些修改,這樣它就不會在 zip 檔案中重新建立工作磁碟機的整個結構

<?php
// 遞迴將目錄、子目錄和檔案新增到 zip 壓縮檔的函式
function addFolderToZip($dir, $zipArchive, $zipdir = ''){
if (
is_dir($dir)) {
if (
$dh = opendir($dir)) {

//新增目錄
if(!empty($zipdir)) $zipArchive->addEmptyDir($zipdir);

// 迴圈處理所有檔案
while (($file = readdir($dh)) !== false) {

//如果它是資料夾,請再次執行函式!
if(!is_file($dir . $file)){
// 跳過父目錄和根目錄
if( ($file !== ".") && ($file !== "..")){
addFolderToZip($dir . $file . "/", $zipArchive, $zipdir . $file . "/");
}

}else{
// 新增檔案
$zipArchive->addFile($dir . $file, $zipdir . $file);

}
}
}
}
}
?>

如果您未指定第三個參數 (zipdir),則您要新增的目錄將會新增到 zip 檔案的根目錄。

D.Jann
-3
Anonymous
16 年前
這是一個簡單的遞迴函式,用於將目錄、所有子目錄和所有檔案新增到已建立的 zip 檔案中;

<?php
// 遞迴地將目錄、
// 子目錄和檔案新增到 zip 封存檔的函式
function addFolderToZip($dir, $zipArchive){
if (
is_dir($dir)) {
if (
$dh = opendir($dir)) {

// 新增目錄
$zipArchive->addEmptyDir($dir);

// 迴圈處理所有檔案
while (($file = readdir($dh)) !== false) {

// 如果是資料夾,再次執行該函式!
if(!is_file($dir . $file)){
// 跳過父目錄和根目錄
if( ($file !== ".") && ($file !== "..")){
addFolderToZip($dir . $file . "/", $zipArchive);
}

}else{
// 新增檔案
$zipArchive->addFile($dir . $file);

}
}
}
}
}
?>

如果能看到更多關於這些函式的輸入就好了:)

Dayjo
To Top