我有以下代码从外部源下载zip文件,然后将其解压缩:
file_put_contents("my-zip.zip", fopen("http://www.externalsite.com/zipfile.zip", 'r'));
$zip = new ZipArchive;
$res = $zip->open('my-zip.zip');
if ($res === TRUE) {
$zip->extractTo('/extract-here');
$zip->close();
//
} else {
//
}
这很好,但我的问题是,解压缩过程是否等到file_put_contents函数完成?或者它会尝试中途运行吗?
它似乎现在正常工作,但我想如果zip文件下载因任何原因而延迟或缓慢,可能会崩溃为什么要尝试解压缩不存在的文件。
如果这是有道理的。
答案 0 :(得分:3)
file_put_contents可以根据主机的不同而有所不同,但据我所知,它的格式不能锁定并发线程(除非严格指定)。同样值得记住的是PHP在Windows上的行为与在linux中的行为不同(很多人,不告诉你,在Windows中开发然后在Linux服务器上部署)
您可以尝试这样的方法来保证文件已成功下载。 (而且没有并发线程同时);
$file = fopen("my-zip.zip", "w+");
if (flock($file, LOCK_EX)) {
fwrite($file, fopen("http://www.externalsite.com/zipfile.zip", 'r'));
$zip = new ZipArchive;
$res = $zip->open('my-zip.zip');
if ($res === TRUE) {
$zip->extractTo('/extract-here');
$zip->close();
//
} else {
//
}
flock($file, LOCK_UN);
} else {
// die("Couldn't download the zip file.");
}
fclose($file);
这也可能有用。
$f = file_put_contents("my-zip.zip", fopen("http://www.externalsite.com/zipfile.zip", 'r'), LOCK_EX);
if(FALSE === $f)
die("Couldn't write to file.");
$zip = new ZipArchive;
$res = $zip->open('my-zip.zip');
if ($res === TRUE) {
$zip->extractTo('/extract-here');
$zip->close();
//
} else {
//
}
如果您将此页面调用两次并且两个页面都尝试访问同一文件,则会阻止此操作。这是可能发生的事情: 第1页下载zip。 第1页开始提取zip。 下载zip替换旧的 第1页就像:我的拉链怎么了? O.O
答案 1 :(得分:0)
尝试这样的事情
function downloadUnzipGetContents($url) {
$data = file_get_contents($url);
$path = tempnam(sys_get_temp_dir(), 'prefix');
$temp = fopen($path, 'w');
fwrite($temp, $data);
fseek($temp, 0);
fclose($temp);
$pathExtracted = tempnam(sys_get_temp_dir(), 'prefix');
$filenameInsideZip = 'test.csv';
copy("zip://".$path."#".$filenameInsideZip, $pathExtracted);
$data = file_get_contents($pathExtracted);
unlink($path);
unlink($pathExtracted);
return $data;
}