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

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

  1. function remote_file_exists($url_file){
  2. //检测输入
  3.     $url_file = trim($url_file);
  4.     if (empty($url_file)) { return false; }
  5.     $url_arr = parse_url($url_file);
  6.     if (!is_array($url_arr) || empty($url_arr)){return false; }
  7. //获取请求数据
  8.     $host = $url_arr['host'];
  9.     $path = $url_arr['path'] ."?".$url_arr['query'];
  10.     $port = isset($url_arr['port']) ?$url_arr['port'] : "80";
  11. //连接服务器
  12.     $fp = fsockopen($host, $port, $err_no, $err_str,30);
  13.     if (!$fp){ return false; }
  14. //构造请求协议
  15.     $request_str = "GET ".$path." HTTP/1.1\r\n";
  16.     $request_str .= "Host:".$host."\r\n";
  17.     $request_str .= "Connection:Close\r\n\r\n";
  18. //发送请求
  19.     fwrite($fp,$request_str);
  20.     $first_header = fgets($fp, 1024);
  21.     fclose($fp);
  22. //判断文件是否存在
  23.     if (trim($first_header) == ""){ return false; }
  24.     if (!preg_match("/200/", $first_header)){ return false; }
  25.     return true;
  26. }

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

  1. // CHECK REMOTE FILE EXISTS
  2. function remote_file_exists($url_file){
  3.     $url_file = trim($url_file);
  4.     if (empty($url_file)) return false;
  5.     $url_arr = parse_url($url_file);
  6.     if (!is_array($url_arr) || empty($url_arr)) return false;
  7.     $host = $url_arr['host'];
  8.     $path = $url_arr['path'] ."?".$url_arr['query'];
  9.     $port = isset($url_arr['port']) ?$url_arr['port'] : "80";
  10.     $fp = fsockopen($host, $port, $err_no, $err_str,30);
  11.     if (!$fp) return false;
  12.     $request_str = "GET ".$path." HTTP/1.1\r\n";
  13.     $request_str .= "Host:".$host."\r\n";
  14.     $request_str .= "Connection:Close\r\n\r\n";
  15.     fwrite($fp,$request_str);
  16.     //fread replace fgets
  17.     $first_header = fread($fp, 128);
  18.     fclose($fp);
  19.     if (trim($first_header) == "") return false;
  20.     //check $url_file "Content-Location"
  21.     if (!preg_match("/200/", $first_header) || preg_match("/Location:/", $first_header)) return false;
  22.     return true;
  23. }
  1. 2010年8月26日 10:55 | #1

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

  2. 2010年8月26日 11:09 | #2

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

emoticons

发表评论