2010-07-28 2 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 является ресурсом, integer given ...», который я нашел, означает, что zip_open() не смог извлечь и возвращает код ошибки, который, как я нашел, 19 "означает" Zip File Function error: не zip-архив ". Тем не менее, я знаю, что файл, который я загружаю, является, по сути, zip-файлом. Может ли кто-нибудь объяснить это странное поведение и обеспечить исправление? Это будет высоко ценится!

+0

Перед выполнением операций zip вам необходимо «fclose ($ file_open)». В этот момент вам больше не нужен дескриптор '$ file_open', и сохранение двух ручек в одном файле является беспорядочным. Я не думаю, что это причина проблемы. – deceze

+0

Да, это имеет смысл, спасибо за помощь в очистке. Но да, поскольку вы предположили, что проблема вообще не изменилась. –

+1

BTW Я очень ценю усилия, чтобы вникать в HTTP таким образом, но вы изучили использование 'file_get_contents (« http: //.../ »)', 'curl_open' и т. Д. И т. Д.? – mvds

ответ

4

Quoting php.net: "zip_open() ... Возвращает дескриптор ресурса для последующего использования с zip_read() и zip_close() или возвращает количество ошибок, если имя файла не существует или в случае другой ошибки."

Это означает, что вы не можете проверить if ($zip) вот так. Попробуйте

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

редактировать: Кроме того, вам нужно отрезать ответ в 2-х частях должным образом. Вы полагаетесь на параметр Content-Length. Вы не проверяете, действительно ли соответствует preg_match. Многое может пойти не так, и вы должны это проверить. Попробуйте разделив содержимое на первой пустой строке (explode на \r\n\r\n или что-то в этом роде)

Кроме петли fread() следует проверить feof(), так как вы бы не читать, если по каким-то причинам вы столкнулись бы пустой читать. Скопируйте & пасту из php.net:

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

Но мы можем пойти дальше и дальше здесь. Три основные точки должны быть сделаны:

  • прочитать чудесное руководство (php.net)
  • проверки Возвращаемых значениями
  • не предполагают, что вы знаете, что вы не

тех связаны: вы должны найти руководство, чтобы узнать, какие возвращаемые значения вы можете встретить.

+0

Путь к преследованию. :) –

+0

Спасибо, это имеет смысл, и я внес изменения, однако теперь вместо того, чтобы печатать ошибки, он просто пропустит часть извлечения, потому что zip_open все еще не может открыть zip-файл. Так что это не решило проблему. –

+0

@ben Затем выясните, почему он не открывает файл. Например, это 'realpath (" packages ")."/". $ File_name' правильный путь? –

Смежные вопросы