PHP下载并解压缩zip文件

时间:2015-03-10 11:48:52

标签: php

我有以下代码从外部源下载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文件下载因任何原因而延迟或缓慢,可能会崩溃为什么要尝试解压缩不存在的文件。

如果这是有道理的。

2 个答案:

答案 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;
}