PHP下载并解压zip文件

Lee*_*Lee 5 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 {
  //
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但是我的问题是,解压缩过程是否等到 file_put_contents 函数完成?或者它会尝试跑到一半?

它现在似乎工作正常,但我在想,如果 zip 文件下载由于任何原因延迟或缓慢,它可能会崩溃,为什么要尝试解压缩不存在的文件。

如果这是有道理的。

Fel*_*ype 7

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);
Run Code Online (Sandbox Code Playgroud)

这也可能有效。

$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 {
  //
}
Run Code Online (Sandbox Code Playgroud)

这将防止您两次调用此页面并且两个页面都尝试访问同一个文件。这就是可能发生的情况:第 1 页下载 zip。第 1 页开始解压缩 zip。第 2 页下载 zip 替换旧的第 1 页将如下所示: 我的 zip 发生了什么变化?面向对象