2010-07-28 107 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