查看网址的最佳方式是什么,响应不是404?
答案 0 :(得分:24)
您可以使用get_headers($url)
<?php
// By default get_headers uses a GET request to fetch the headers. If you
// want to send a HEAD request instead, you can do so using a stream context:
stream_context_set_default(
array(
'http' => array(
'method' => 'HEAD'
)
)
);
print_r(get_headers('http://example.com'));
// gives
Array
(
[0] => HTTP/1.1 200 OK
[Date] => Sat, 29 May 2004 12:28:14 GMT
[Server] => Apache/1.3.27 (Unix) (Red-Hat/Linux)
[Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT
[ETag] => "3f80f-1b6-3e1cb03b"
[Accept-Ranges] => bytes
[Content-Length] => 438
[Connection] => close
[Content-Type] => text/html
)
第一个数组元素将包含HTTP响应状态代码。你必须解析它。
请注意,示例中的get_headers
函数将发出HTTP HEAD请求,这意味着它不会获取URL的正文。这比使用GET请求更有效,GET请求也会返回正文。
另请注意,通过设置默认上下文,使用http流上下文的任何后续调用现在都会发出HEAD请求。因此,请确保重置默认上下文,以便在完成后再次使用GET。
PHP还提供了variable $http_response_header
$http_response_header
数组类似于get_headers()
函数。使用HTTP wrapper时,$http_response_header
将填充HTTP响应标头。将在本地范围内创建$http_response_header
。
如果要下载远程资源的内容,则不希望执行两个请求(一个用于查看资源是否存在以及一个用于获取资源),而只需要一个。在这种情况下,使用file_get_contents
之类的内容来获取内容,然后检查变量中的标题。
答案 1 :(得分:0)
@Gordon - 根据您的回答,这是一个更完整的库例程。它包括对URL有效性的一些初步检查,一些错误处理以及解析返回的头文件。它还遵循任何重定向链以获得合理数量的步骤。
class cLib {
static $lasterror = 'No error set yet';
/**
* @brief See with a URL is valid - i.e. a page can be successfully retrieved from it without error
* @param string $url The URL to be checked
* @param int $nredirects The number of redirects check so far
* @return boolean True if OK, false if the URL cannot be fetched
*/
static function checkUrl($url, $nredirects = 0) {
// First, see if the URL is sensible
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
self::$lasterror = sprintf('URL "%s" did not validate', $url);
return false;
}
// Now try to fetch it
$headers = @get_headers($url);
if ($headers == false) {
$error = error_get_last();
self::$lasterror = sprintf('URL "%s" could not be read: %s', $url, $error['message']);
return false;
}
$status = $headers[0];
$rbits = explode(' ', $status);
if (count($rbits) < 2) {
self::$lasterror = sprintf('Cannot parse status "%s" from URL "%s"', $status, $url);
return false;
}
if (in_array($rbits[1], array(301, 302, 304, 307, 308))) {
// This URL has been redirected. Follow the redirection chain
foreach ($headers as $header) {
if (cLib::startsWith($header, 'Location:')) {
if (++$nredirects > 10) {
self::$lasterror = sprintf('URL "%s" was redirected over 10 times: abandoned check', $url);
return false;
}
return self::checkUrl(trim(substr($header, strlen('Location:'))), $nredirects);
}
}
self::$lasterror = sprintf('URL "%s" was redirected but location could not be identified', $url);
return false;
}
if ($rbits[1] != 200) {
self::$lasterror = sprintf('URL "%s" returned status "%s"', $url, $status);
return false;
}
return true;
}
}
向@FranciscoLuz道歉 - 如果您根据用户输入预期错误,&#34; @和error_get_last&#34;方法对我来说似乎非常明智 - 我没有看到使用set_error_handler更合适。
顺便说一句,不知道我是否应该这样做是为了编辑@Gordon的答案,而不是作为一个单独的答案。有人可以建议吗?答案 2 :(得分:0)
public function isLink($url)
{
$result = false;
if (!filter_var($url, FILTER_VALIDATE_URL) === false) {
$getHeaders = get_headers($url);
$result = strpos($getHeaders[0], '200') !== false;
}
return $result;
}
答案 3 :(得分:0)
我正在使用此函数,因为它还会验证并返回URL的协议(如果找不到)。
$theUrl = 'google.com';
function isValidURL($url) {
$urlRegex = '@(http(s)?)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
if(preg_match($urlRegex, $url)){
return preg_replace($urlRegex, "http$2://$4", $url);
} else {
return false;
}
}
var_dump(isValidURL($theUrl));