在PHP中创建和下载zip文件也有类似的问题,我可以做到这一点。问题是有些zip文件更大(〉200 MB),PHP不会等到zip文件完成后才开始下载。
压缩的速度还可以。我试过存储未压缩的文件,只是稍微快一点,并没有解决问题。
创建zip文件的函数如下所示:
function makeRouteArchive($routeID) {
// Get real path for our folder
$rootPath = self::get_location($routeID);
$relRootPath = $rootPath;
while (!scandir($relRootPath)) {
$relRootPath = '../'.$relRootPath;
}
$info = new SplFileInfo($relRootPath);
$rootlen = strlen( $info->getRealPath());
$zippath = $this->archive_root;
while (!scandir($zippath)){
$zippath = '../'.$zippath;
}
$routeText = 'oute'.sprintf('%07d',$routeID);
$zipfilename = 'route'.sprintf('%07d',$routeID).'.zip';
$zipfile = $zippath.$zipfilename;
// Initialize archive object
$zip = new ZipArchive();
// Create recursive directory iterator
/** @var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($relRootPath), RecursiveIteratorIterator::SELF_FIRST );
$zip->open($zipfile, ZipArchive::CREATE | ZipArchive::OVERWRITE);
foreach ($files as $name => $file)
{
// Skip directories (they would be added automatically)
if (!$file->isDir())
{
// Get real and relative path for current file
$filePath = $file->getRealPath();
$relativePath = substr($filePath, $rootlen + 1);
if (!strpos($relativePath,$routeText) === false) {
if (strpos($relativePath,'Picture_') > 0) {
$relativePath = str_replace('Picture_','Pictures/',$relativePath);
$relativePath = 'Storage Card/RoutAbel/'.$relativePath;
} elseif (strpos($relativePath,'Media_') > 0) {
$relativePath = str_replace('Media_','Media/',$relativePath);
$relativePath = 'Storage Card/RoutAbel/'.$relativePath;
} elseif (strpos($relativePath,'ARobjects_') > 0) {
$relativePath = str_replace('ARobjects_','ARobjects/',$relativePath);
$relativePath = 'Storage Card/RoutAbel/'.$relativePath;
} elseif (strpos($relativePath,'_') == 12 ) {
$relativePath = 'Storage Card/RoutAbel/'.substr_replace($relativePath,'/Content/',12,1);
$relativePath = str_replace('_Marker','/Content/Marker', $relativePath);
$relativePath = str_replace('_Slider','/Content/Slider', $relativePath);
}
// Add current file to archive
$zip->addFile($filePath, $relativePath);
}
}
}
// Zip archive will be created only after closing object
$zip->close();
return $result;
}
主要代码如下:
$zipfile = makeRouteArchive($routeID);
if (headers_sent()) {
echo 'HTTP header already sent';
} else {
if (!is_file($zipfile)) {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
echo 'File not found';
} else if (!is_readable($zipfile)) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
echo 'File not readable';
} else {
while (ob_get_level()) {
ob_end_clean();
}
ob_start();
header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-Length: ".filesize($file));
header('Pragma: no-cache');
header("Content-Disposition: attachment; filename=\"".basename($zipfile)."\"");
ob_flush();
ob_clean();
readfile($zipfile);
exit;
}
}
代码是完美的工作,只要没有太多或太大的文件要压缩。
**我的问题:**如何强制函数等待zip文件准备好?
1条答案
按热度按时间yhqotfr81#
ob_start()会导致例程清除缓冲区,从而使例程无法完成zip文件的创建