Скрипт для загрузки и распаковки zip-файлов возвращает ошибки - PullRequest
1 голос
/ 28 июля 2010

Привет всем, я написал скрипт, который загружает 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.Может кто-нибудь объяснить это странное поведение и предоставить исправление?Это будет высоко ценится!

1 Ответ

4 голосов
/ 28 июля 2010

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

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

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

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

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

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

Но мы можем продолжать и продолжать здесь. Необходимо сделать три основных замечания:

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

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

...