2010-07-28 148 views
1

嘿大家,我已经写了一个脚本,从远程源下载zip文件,然后应该解压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是资源,给定的整数...”,我发现这意味着zip_open()无法提取并返回一个错误代码,我发现它是“ 19“,意思是”Zip文件功能错误:不是zip压缩文件“。但是,我知道我下载的文件实际上是一个zip文件。任何人都可以解释这种奇怪的行为并提供修复吗?这将非常感谢!

+0

在执行压缩操作之前,您应该'fclose($ file_open)'。在这一点上,您不再需要'$ file_open'手柄,并且在同一个文件上保留两个手柄是很麻烦的。我不认为这是问题的原因。 – deceze 2010-07-28 01:24:51

+0

是的,这是有道理的,谢谢你帮忙清理。但是,是的,正如你所建议的,这个问题一点都没有改变。 – 2010-07-28 01:40:50

+1

顺便说一句,我真的很喜欢这种方式来研究HTTP,但你有没有使用'file_get_contents(“http://.../”)','curl_open'等等? – mvds 2010-07-28 01:54:13

回答

4

引用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)
  • 检查返回值
  • 不要以为你知道你做的事情没有

那些是相关的:您必须查阅手册以查看您可能遇到的返回值。

+0

方式切入追逐。 :) – 2010-07-28 01:29:05

+0

谢谢,这是有道理的,我做了改变,但现在,而不是打印错误,它只会跳过提取部分,因为zip_open仍然无法打开zip文件。所以这并没有解决问题。 – 2010-07-28 01:39:20

+0

@ben然后找出为什么它不打开文件。例如,是'realpath(“packages”)。“/”。$ file_name'的正确路径? – 2010-07-28 01:48:40