function packageZip($name, $path) { $zip = new ZipArchive(); if (!$zip->open($name, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) { return false; } $php56 = version_compare(phpversion(), '5.6.0', '>'); $addFiles = function ($dir) use(&$addFiles, $zip, $path, $php56) { $files = array_diff(scandir($dir), array('.', '..')); $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; foreach ($files as $file) { $full = "{$dir}/{$file}"; $local = str_replace($path, '', $full); if (is_dir($full)) { $addFiles($full); } else { // XXX: AddFile() will keep the file open and run // out of OS open file handles $zip->addFromString($local, file_get_contents($full)); } // This only works on PHP >= v5.6 if ($php56) { // Set the Unix mode of the file $stat = stat($full); $zip->setExternalAttributesName($local, ZipArchive::OPSYS_UNIX, $stat['mode']); } } }; $addFiles($path); return $zip->close(); }
<?php $name = __DIR__ . '/withattr.zip'; echo "== Set\n"; $zip = new ZipArchive(); $r = $zip->open($name, ZIPARCHIVE::CREATE); $zip->addFromString('foo.txt', 'foo'); $zip->addFromString('bar.txt', 'bar'); var_dump($zip->setExternalAttributesName('foo.txt', ZipArchive::OPSYS_UNIX, 123)); $id = $zip->locateName('bar.txt'); var_dump($zip->setExternalAttributesIndex($id, ZipArchive::OPSYS_VFAT, 234)); $zip->close(); echo "== Get\n"; $r = $zip->open($name); var_dump($zip->getExternalAttributesName('foo.txt', $a, $b), $a, $b); $id = $zip->locateName('bar.txt'); var_dump($zip->getExternalAttributesIndex($id, $a, $b), $a, $b); echo "== Set\n"; var_dump($zip->setExternalAttributesName('foo.txt', ZipArchive::OPSYS_DOS, 345)); var_dump($zip->setExternalAttributesIndex($id, ZipArchive::OPSYS_AMIGA, 456)); echo "== Get changed\n"; var_dump($zip->getExternalAttributesName('foo.txt', $a, $b), $a, $b); var_dump($zip->getExternalAttributesIndex($id, $a, $b), $a, $b); echo "== Get unchanged\n"; var_dump($zip->getExternalAttributesName('foo.txt', $a, $b, ZipArchive::FL_UNCHANGED), $a, $b); var_dump($zip->getExternalAttributesIndex($id, $a, $b, ZipArchive::FL_UNCHANGED), $a, $b); $zip->close(); ?> == Done