关于php判断远程文件是否存在的函数(remote_file_exists)的缺陷

检查远程文件是否存在的方法有几种,其中比较被大家常用的是get_headers。一般都是通过获取文件头的方式来判断,而且如果在网上搜索一下“remote_file_exists”的话,会有很多例程,这里被大家常常转载的一段代码如下:

function remote_file_exists($url_file){
//检测输入
	$url_file = trim($url_file);
	if (empty($url_file)) { return false; }
	$url_arr = parse_url($url_file);
	if (!is_array($url_arr) || empty($url_arr)){return false; }
//获取请求数据
	$host = $url_arr['host'];
	$path = $url_arr['path'] ."?".$url_arr['query'];
	$port = isset($url_arr['port']) ?$url_arr['port'] : "80";
//连接服务器
	$fp = fsockopen($host, $port, $err_no, $err_str,30);
	if (!$fp){ return false; }
//构造请求协议
	$request_str = "GET ".$path." HTTP/1.1\r\n";
	$request_str .= "Host:".$host."\r\n";
	$request_str .= "Connection:Close\r\n\r\n";
//发送请求
	fwrite($fp,$request_str);
	$first_header = fgets($fp, 1024);
	fclose($fp);
//判断文件是否存在
	if (trim($first_header) == ""){ return false; }
	if (!preg_match("/200/", $first_header)){ return false; }
	return true;
}

这个方法里有一点需特别注意,在“$request_str = "GET ".$path." HTTP/1.1\r\n";”句中,“GET”后面的空格一定不能落下,而“HTTP”前面的空格也不能落下,至少我曾经因为这个问题而造成该函数读取不到文件信息头。但该段代码仍有一个缺陷,其中就是它使用了“fgets”读取头部第一行信息,只要该信息中存在“200”即认为要判断的文件存在,在文件名完全正确或错误的时候,该方法可行,不过如果你将文件的扩展名去掉(比如某个图片,将后面的扩展名去掉)一样可以得到该文件存在的消息。我在参考了PHP官网上老外的写法后修改整理为如下代码,在测试运行后发现可行,在此贴给大家,希望能够对大家有所帮助。代码如下:

// CHECK REMOTE FILE EXISTS
function remote_file_exists($url_file){
	$url_file = trim($url_file);
    if (empty($url_file)) return false;
    $url_arr = parse_url($url_file);
    if (!is_array($url_arr) || empty($url_arr)) return false;
    $host = $url_arr['host'];
    $path = $url_arr['path'] ."?".$url_arr['query'];
    $port = isset($url_arr['port']) ?$url_arr['port'] : "80";
    $fp = fsockopen($host, $port, $err_no, $err_str,30);
    if (!$fp) return false;
    $request_str = "GET ".$path." HTTP/1.1\r\n";
    $request_str .= "Host:".$host."\r\n";
    $request_str .= "Connection:Close\r\n\r\n";
    fwrite($fp,$request_str);
	//fread replace fgets
    $first_header = fread($fp, 128);
    fclose($fp);
    if (trim($first_header) == "") return false;
	//check $url_file "Content-Location"
    if (!preg_match("/200/", $first_header) || preg_match("/Location:/", $first_header)) return false;
    return true;
}
喜欢 0

这篇文章有2条评论

  1. 德海 (作者) 2010/8/26 #1 [REPLY]

    @严重浪漫
    coolcode,很早的一个插件,多数人不太喜欢用,因为它要加载自己的JS,不过我个人还是比较喜欢这个插件的,比我另一个博里贴代码的插件要感觉好一些,如果找不到下载请向我索取。

  2. 严重浪漫 2010/8/26 #2 [REPLY]

    博主你好,你的代码显示的真漂亮啊,是用的啥插件?
    俺用的是WP-Syntax ,没有你的代码显示好看

发表评论