【发布时间】:2011-03-21 22:10:55
【问题描述】:
大家好,我编写了一个脚本,可以从远程源下载 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 文件。谁能解释这种奇怪的行为并提供修复?将不胜感激!
【问题讨论】:
-
您应该在进行压缩操作之前
fclose($file_open)。此时您不再需要$file_open句柄,并且在同一个文件中保留两个句柄很麻烦。不过,我认为这不是问题的原因。 -
是的,这是有道理的,感谢您帮助清理。但是,是的,正如你所说,这个问题根本没有改变。
-
顺便说一句,我非常感谢以这种方式深入研究 HTTP 的努力,但是您是否考虑过使用
file_get_contents("http://.../")、curl_open等? -
zip 常量页面的注释中有一个错误代码列表:php.net/manual/en/zip.constants.php(我不知道它们是否正确,但它可能有用。)
-
@mvds 我还没有,但它可能是我需要去的地方。它现在和将来可能会省去一些麻烦。我以前从未做过任何获取/读取远程文件的工作,所以我边走边学。我会看看这两个选项。我以前听说过关于 curl 的好消息。 @George 感谢您的信息,看起来很棒!