方法一:get_headers

function url_exists($url) {
    if (!is_string($url) || empty($url)) {
        return false;
    }
    $head=@get_headers($url);
    if(is_array($head)) {
        return true;
    }
    return false;
}

或者

function file_exits($url){
    $head=@get_headers($url);
    if ($head[0] == 'HTTP/1.1 200 OK') {
        return true;
    }
    return false;
}

方法二:curl

function check_remote_file_exists($url) {
    $curl = curl_init($url); // 不取回数据
    curl_setopt($curl, CURLOPT_NOBODY, true);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET'); // 发送请求
    $result = curl_exec($curl);
    $found = false; // 如果请求没有发送失败
    if ($result !== false) {

        /** 再检查http响应码是否为200 */
        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        if ($statusCode == 200 || $statusCode == 301) {
            $found = true;
        }
    }
    curl_close($curl);

    return $found;
}

局限性

使用的核心方法是 get_headers,该方法声明如下:

Fetches all the headers sent by the server in response to a HTTP request

意思只能获取 http 请求服务器返回的所有 headers 设置。

所以对于判断 https 下的文件资源是否存在无效。经测试,https 请求全部都返回 false

其他不能判断的方法

fopen file_get_contents file_exits

还有这个也不行,连接时间还特别长:

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";
    $request_str .= "Host:".$host."";
    $request_str .= "Connection:Close";

    //发送请求
    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;
}