php 关于使用 ZipArchive 生成ZIP文件,下载解压出现多级目录问题
sanlanlan 2018-10-11 标签: PHP 浏览:2555 评论:0
使用php ZipArchive 来进行在线生成zip 文件,是一个常见的应用。
但,在使用的时候,出现一个问题,就是在线生成的ZIP文件,下载解压下来之后,出现多级目录的情况,
比如解压后出现:var/local/data/zip 类似这样
这样不是想要的结果。
解决这个问题的关键是:
addFile
这个函数。
bool ZipArchive::addFile ( string $filename
[, string $localname
= NULL
[, int $start
= 0 [, int$length
= 0 ]]] )
$localname 如果不配置的话,默认是 $filename 的路径
$oZip->addFile ( $file_name, " " . basename ( $file_name ) )
如果配置成这样,可以解决多级目录的问题,但是会出现,文件都在根目录下,原先的目录层级消失了。
所以应该这样做,
$filename 使用绝对路径
$localname 使用 $filename 对应的相对路径
代码如下:
function generateZip($file_list, $filename)
{
$zip = new \ZipArchive();
foreach ($file_list as $abs_path) {
if (is_dir($abs_path)) {
if ($zip->open($filename, \ZipArchive::CREATE) === true) {
addDirectoryToZip($abs_path, $zip);
}
}
if (is_file($abs_path)) {
if ($zip->open($filename, \ZipArchive::CREATE) === true) {
$relative_path = str_replace(__DIR__.'/../../data/', '../../../../', $abs_path); //相对路径
$zip->addFile($abs_path, $relative_path);
}
}
$zip->close();
}
}
function addDirectoryToZip($abs_path, $zip)
{
$handler = opendir($abs_path);
while (($filename = readdir($handler)) !== false) {
if ($filename != "." && $filename != "..") {
if (is_dir($abs_path."/".$filename)) {
addDirectoryToZip($abs_path."/".$filename, $zip);
} else {
$relative_path = str_replace(__DIR__.'/../../data/', '../../../../', $abs_path); //相对路径
$zip->addFile($abs_path."/".$filename, $relative_path);
}
}
}
@closedir($abs_path);
}
下载文件
如果是以 Response 形式返回
public function downloadFile($file, $filename='')
{
$filename = $filename ? $filename : basename($file);
$filetype = strtolower(trim(substr(strrchr($filename, '.'), 1)));
ini_set("memory_limit", "1024M");
ob_end_clean();
@set_time_limit(0);
$response = new Response();
$response->headers->set('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
$response->headers->set('Expires', gmdate('D, d M Y H:i:s') . ' GMT');
$response->headers->set('Content-Encoding', 'none');
$response->headers->set('Content-type', $filetype);
$response->headers->set('Content-Disposition', 'attachment; filename=' . $filename);
$response->headers->set('Content-length', filesize($file));
$response->sendHeaders();
$response->setContent(file_get_contents($file)); //
$response->send(); //
return $response;
}
如果直接返回
public function fileDown($file, $filename = '') {
if (!$data && !is_file($file))
exit;
$filename = $filename ? $filename : basename($file);
$$filetype = strtolower(trim(substr(strrchr($filename, '.'), 1)));
ini_set("memory_limit", "1024M");
ob_end_clean();
@set_time_limit(0);
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) {
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
} else {
header('Pragma: no-cache');
}
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Content-Encoding: none');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename=' . $filename);
header('Content-Type: ' . $filetype);
readfile($file);
exit;
}
发表评论: