下载和解压 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 是资源,给定整数...”,我发现这意味着 < code>zip_open() 无法解压并返回错误代码,我发现该代码是“19”,意思是“Zip 文件函数错误:不是 zip 存档”。但是,我知道我正在下载的文件实际上是一个 zip 文件。任何人都可以解释这种奇怪的行为并提供解决方案吗?我们将不胜感激!
Hey everyone, I have written a script that downloads a zip file from a remote source, and then is supposed to extract the zip file to a directory. Below is the script:
<?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;
}
?>
The issue that I have is that while the downloading of the remote file works flawlessly, I can't seem to extract it. The zip_read()
and zip_close()
return errors saying that it "expects parameter 1 to be resource, integer given...", which I have found means that the zip_open()
was unable to extract and is returning an error code, which I have found to be "19" meaning "Zip File Function error: Not a zip archive". However, I know the file I am downloading is, in fact, a zip file. Can anyone explain this odd behavior and provide a fix? It would be much appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
引用 php.net:“zip_open() ...返回一个资源句柄,以便稍后与 zip_read() 和 zip_close() 一起使用,或者如果文件名不存在或出现其他错误,则返回错误数量。”
这意味着您无法像这样测试
if ($zip)
。尝试编辑: 除此之外,您需要将响应正确地分成两部分。您严重依赖
Content-Length
参数。您不检查preg_match
是否实际匹配。很多事情都可能出错,您应该检查这些事情。尝试在第一个空行上拆分内容(\r\n\r\n
上的explode
或类似的内容)除了
fread()
循环应该检查feof()
,因为如果由于某种原因您遇到空读取,您现在就会停止读取。从 php.net 复制并粘贴:但是我们可以在这里继续下去。必须指出三个要点:
:您必须查找手册以了解可能遇到的返回值。
Quoting php.net: "zip_open() ... Returns a resource handle for later use with zip_read() and zip_close() or returns the number of error if filename does not exist or in case of other error."
This means you cannot test
if ($zip)
like that. Tryedit: Apart from that, you need to cut the response in 2 parts properly. You are relying heavily on the
Content-Length
parameter. You don't check if thepreg_match
actually matched. A lot of things can go wrong and you should check those things. Try splitting the content on the first empty line (explode
on\r\n\r\n
or something like that)Besides the
fread()
loop should check forfeof()
, since you would stop reading now if for some reason you would encounter an empty read. Copy&paste from php.net:But we can go on and on here. Three main points have to be made:
those are related: you must lookup the manual to see what return values you might encounter.