下载和解压 zip 文件的脚本返回错误

发布于 2024-09-12 09:37:56 字数 2101 浏览 1 评论 0原文

大家好,我编写了一个脚本,从远程源下载 zip 文件,然后将 zip 文件解压到目录中。下面是脚本:

    <?php
        $url = "http://example.com/some_file.zip";
        download($url,'file.zip');

        function download($url,$file_name = NULL){
          if($file_name == NULL){ $file_name = basename($url);}

          $url_stuff = parse_url($url);
          $port = isset($url_stuff['port']) ? $url_stuff['port'] : 80;

          $fp = fsockopen($url_stuff['host'], $port);
          if(!$fp){ return false;}

          $query  = 'GET ' . $url_stuff['path'] . " HTTP/1.0\n";
          $query .= 'Host: ' . $url_stuff['host'];
          $query .= "\n\n";

          fwrite($fp, $query);

          while ($tmp = fread($fp, 8192))   {
            $buffer .= $tmp;
          }

          preg_match('/Content-Length: ([0-9]+)/', $buffer, $parts);
          $file_binary = substr($buffer, - $parts[1]);
          if($file_name == NULL){
            $temp = explode(".",$url);
            $file_name = $temp[count($temp)-1];
          }
          if(!file_exists("packages")){ mkdir("packages", 0755);}
          $file_open = fopen("packages/" . $file_name,'w');
          if(!$file_open){ return false;}
          fwrite($file_open,$file_binary);

          $zip = zip_open(realpath("packages")."/".$file_name);
          if ($zip) {
            while ($zip_entry = zip_read($zip)) {
              $fp = fopen("some_dir/".zip_entry_name($zip_entry), "w");
              if(zip_entry_open($zip, $zip_entry, "r")) {
                $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
                fwrite($fp,"$buf");
                zip_entry_close($zip_entry);
                fclose($fp);
              }
            }
            zip_close($zip);
          }
          fclose($file_open);
          return true;
        }
   ?>

我遇到的问题是,虽然远程文件的下载工作正常,但我似乎无法提取它。 zip_read()zip_close() 返回错误,表示它“期望参数 1 是资源,给定整数...”,我发现这意味着 < code>zip_open() 无法解压并返回错误代码,我发现该代码是“19”,意思是“Zip 文件函数错误:不是 zip 存档”。但是,我知道我正在下载的文件实际上是一个 zip 文件。任何人都可以解释这种奇怪的行为并提供解决方案吗?我们将不胜感激!

Hey everyone, I have written a script that downloads a zip file from a remote source, and then is supposed to extract the zip file to a directory. Below is the script:

    <?php
        $url = "http://example.com/some_file.zip";
        download($url,'file.zip');

        function download($url,$file_name = NULL){
          if($file_name == NULL){ $file_name = basename($url);}

          $url_stuff = parse_url($url);
          $port = isset($url_stuff['port']) ? $url_stuff['port'] : 80;

          $fp = fsockopen($url_stuff['host'], $port);
          if(!$fp){ return false;}

          $query  = 'GET ' . $url_stuff['path'] . " HTTP/1.0\n";
          $query .= 'Host: ' . $url_stuff['host'];
          $query .= "\n\n";

          fwrite($fp, $query);

          while ($tmp = fread($fp, 8192))   {
            $buffer .= $tmp;
          }

          preg_match('/Content-Length: ([0-9]+)/', $buffer, $parts);
          $file_binary = substr($buffer, - $parts[1]);
          if($file_name == NULL){
            $temp = explode(".",$url);
            $file_name = $temp[count($temp)-1];
          }
          if(!file_exists("packages")){ mkdir("packages", 0755);}
          $file_open = fopen("packages/" . $file_name,'w');
          if(!$file_open){ return false;}
          fwrite($file_open,$file_binary);

          $zip = zip_open(realpath("packages")."/".$file_name);
          if ($zip) {
            while ($zip_entry = zip_read($zip)) {
              $fp = fopen("some_dir/".zip_entry_name($zip_entry), "w");
              if(zip_entry_open($zip, $zip_entry, "r")) {
                $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
                fwrite($fp,"$buf");
                zip_entry_close($zip_entry);
                fclose($fp);
              }
            }
            zip_close($zip);
          }
          fclose($file_open);
          return true;
        }
   ?>

The issue that I have is that while the downloading of the remote file works flawlessly, I can't seem to extract it. The zip_read() and zip_close() return errors saying that it "expects parameter 1 to be resource, integer given...", which I have found means that the zip_open() was unable to extract and is returning an error code, which I have found to be "19" meaning "Zip File Function error: Not a zip archive". However, I know the file I am downloading is, in fact, a zip file. Can anyone explain this odd behavior and provide a fix? It would be much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝不放开 2024-09-19 09:37:56

引用 php.net:“zip_open() ...返回一个资源句柄,以便稍后与 zip_read() 和 zip_close() 一起使用,或者如果文件名不存在或出现其他错误,则返回错误数量。”

这意味着您无法像这样测试 if ($zip) 。尝试

if ( is_resource($zip) ) {
    // stuff
} else {
    print "Zip_open() returned error $zip\n";
}

编辑: 除此之外,您需要将响应正确地分成两部分。您严重依赖 Content-Length 参数。您不检查 preg_match 是否实际匹配。很多事情都可能出错,您应该检查这些事情。尝试在第一个空行上拆分内容(\r\n\r\n 上的 explode 或类似的内容)

除了 fread() 循环应该检查 feof(),因为如果由于某种原因您遇到空读取,您现在就会停止读取。从 php.net 复制并粘贴:

while (!feof($handle)) {
    $contents .= fread($handle, 8192);
}

但是我们可以在这里继续下去。必须指出三个要点:

  • 阅读精彩的手册 (php.net)
  • 检查返回值
  • 不要假设您知道您不知道的事情

:您必须查找手册以了解可能遇到的返回值。

Quoting php.net: "zip_open() ... Returns a resource handle for later use with zip_read() and zip_close() or returns the number of error if filename does not exist or in case of other error."

This means you cannot test if ($zip) like that. Try

if ( is_resource($zip) ) {
    // stuff
} else {
    print "Zip_open() returned error $zip\n";
}

edit: Apart from that, you need to cut the response in 2 parts properly. You are relying heavily on the Content-Length parameter. You don't check if the preg_match actually matched. A lot of things can go wrong and you should check those things. Try splitting the content on the first empty line (explode on \r\n\r\n or something like that)

Besides the fread() loop should check for feof(), since you would stop reading now if for some reason you would encounter an empty read. Copy&paste from php.net:

while (!feof($handle)) {
    $contents .= fread($handle, 8192);
}

But we can go on and on here. Three main points have to be made:

  • read the fantastic manual (php.net)
  • check return values
  • don't assume you know things you don't

those are related: you must lookup the manual to see what return values you might encounter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文