温馨提示:
本文所述内容具有依赖性,可能因软硬条件不同而与预期有所差异,故请以实际为准,仅供参考。
PHP 开发中,经常遇到需要下载远程文件,此时可以通过 curl
函数方法获取,也可以使用 file_get_contents
函数方法获取。
在使用 file_get_contents
函数时,有时候需要先判断远程 URL 链接是否有效,参考下列代码:
function getUrl($url) {
$content = file_get_contents($url);
return array(
'headers' => $http_response_header,
'content' => $content
);
}
$response = getUrl('https://vircloud.net/robots.txt');
if ($response['content'] === false)
echo $response['headers'][0]; // HTTP/1.1 401 Unauthorized
else
echo $response['content'];
每次使用 file_get_contents
调用 HTTP 请求时,都会在本地创建动态变量:$http_response_header
,此变量包含了所有 HTTP 标头。
举例
请求如下:<?php function get_contents() { file_get_contents("https://vircloud.net"); return $http_response_header; } var_dump(get_contents()); ?>
响应如下:
array(12) { [0] => string(15) "HTTP/1.1 200 OK" [1] => string(35) "Date: Tue, 13 Aug 2019 05:39:50 GMT" [2] => string(38) "Content-Type: text/html; charset=UTF-8" [3] => string(17) "Connection: close" [4] => string(21) "Vary: Accept-Encoding" [5] => string(46) "X-Pingback: https://vircloud.net/action/xmlrpc" [6] => string(70) "Set-Cookie: 1ace4129ed475fea40c32ab2c48ab0c2_armxmod_online=U1; path=/" [7] => string(14) "Server: vcloud" [8] => string(71) "Strict-Transport-Security: max-age=15552000; includeSubdomains; preload" [9] => string(31) "X-Xss-Protection: 1; mode=block" [10] => string(31) "X-Content-Type-Options: nosniff" [11] => string(27) "X-Frame-Options: SAMEORIGIN" }
还可以使用 get_headers
函数来判断链接有效性,参见下列代码:
function file_contents_exist($url, $response_code = 200) {
$headers = get_headers($url);
if (substr($headers[0], 9, 3) == $response_code) {
return TRUE;
} else {
return FALSE;
}
}
$file_path = 'https://vircloud.net';
if(file_contents_exist($file_path)) {
$file = file_get_contents($file_path);
}
或者使用 curl
函数:
function fetchUrl($uri) {
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $uri);
curl_setopt($handle, CURLOPT_POST, false);
curl_setopt($handle, CURLOPT_BINARYTRANSFER, false);
curl_setopt($handle, CURLOPT_HEADER, true);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 10);
$response = curl_exec($handle);
$hlength = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
$body = substr($response, $hlength);
// If HTTP response is not 200, throw exception
if ($httpCode != 200) {
throw new Exception($httpCode);
}
return $body;
}
$url = 'https://vircloud.net';
try {
$response = fetchUrl($url);
} catch (Exception $e) {
error_log('Fetch URL failed: ' . $e->getMessage() . ' for ' . $url);
}
虽然三个方法都可以满足需求,但相比之下,用 get_headers
函数判断 URL 标头,会执行两个请求,而 curl
方法构造麻烦,因此第一种方法将会是最优方法。
需要注意的是,get_headers
和 file_get_contents
两个函数的请求,可能响应不同。例如,get_headers
返回 503,而 file_get_contents
可能返回 200。
参考文章:
1、《file_get_contents when url doesn't exist》
2、《$http_response_header》
Windows 10Chrome 75.0.3770.80来自 福建 的大神
file_get_contents 确实好用,简单方便
是的哟,之前没发现还会修改 header 信息,这下齐全了
Windows 7Internet Explorer 11来自 江西 的大神
如果网络环境不佳的话,file_get_contents好像会出大问题。
所以要先判断链接能不能连上不是