简体   繁体   English

PHP下载并解压缩zip文件

[英]PHP download and extract zip file

I have the following code that downloads a zip file from an external source and then extracts it: 我有以下代码,该代码从外部来源下载一个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 {
  //
}

This works fine, however my question is, does the unzipping procedure wait until the file_put_contents function is complete? 这可以正常工作,但是我的问题是,解压缩过程是否要等到file_put_contents函数完成? Or will it try and run half way through? 还是会尝试运行一半?

It seems to work fine right now but I'm thinking that if the zip file download is delayed or slow for whatever reason that it may crash why trying to unzip a file that doesn't exist. 现在看来似乎可以正常工作,但我在想,如果由于任何原因导致zip文件下载延迟或缓慢,则可能会导致尝试解压缩不存在的文件的原因。

If that makes sense. 如果这样的话。

file_put_contents can work differently depending on the host machine, but as far as I can tell its format doesn't lock concurrent threads as one should expect (unless strictly specified). file_put_contents的工作方式可能因主机而异,但据我所知,它的格式并没有像人们期望的那样锁定并发线程(除非严格指定)。 Also good to remember PHP behaves differently on windows than it does in linux (and many people, not telling you do, develop in windows to then deploy on a linux server) 同样要记住,PHP在Windows上的行为与在Linux上的行为有所不同(很多人(并没有告诉您)是在Windows中进行开发,然后在Linux服务器上进行部署)

You can try something like this to guarantee that the file was successfully downloaded. 您可以尝试执行类似的操作,以确保文件已成功下载。 (And that no concurrent thread same time); (并且同时没有并发线程);

$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);

This might also work. 这也可能起作用。

$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 {
  //
}

This will prevent in case you call this page twice and both pages try to access the same file. 这样可以防止您两次调用此页面,并且两个页面都尝试访问同一文件。 This is what could happen: Page 1 downloads zip. 这是可能发生的情况:第1页下载zip。 Page 1 starts extracting zip. 页面1开始提取zip。 Page 2 downloads zip replacing the old one Page 1 will be like: What happened to my zip? Page 2下载zip取代旧的zip Page 1将像:我的zip发生了什么? OO 面向对象

Try something like this 试试这个

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM