检查PHP中是否存在URL的最佳方法是什么?

什么是最好的方式来看到一个url存在和响应不是404?

你可以使用get_headers($url)

手册中的示例2 :

 <?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响应状态代码。 你必须parsing这个。

请注意,示例中的get_headers函数将发出HTTP HEAD请求,这意味着它不会获取URL的主体。 这比使用也会返回正文的GET请求更有效率。

另请注意,通过设置默认上下文,使用httpstream上下文的任何后续调用现在将发出HEAD请求。 因此,确保在完成时重置默认上下文以再次使用GET。

PHP也提供variables$ http_response_header

$http_response_header数组类似于get_headers()函数。 当使用HTTP包装器时 , $http_response_header将填充HTTP响应标头。 $http_response_header将在本地范围内创build。

如果要下载远程资源的内容,则不需要执行两个请求(一个用于查看资源是否存在,另一个用于获取资源),但只有一个。 在这种情况下,使用类似file_get_contents东西来获取内容,然后检查variables中的头文件。

@Gordon – 根据你的回答,这是一个更完整的库例程。 它包括一些初步的URL有效性检查,一些更多的error handling和parsing返回的头文件。 它也遵循任何redirect链的合理步骤。

 class cLib { static $lasterror = 'No error set yet'; /** * @brief See with a URL is valid - ie 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道歉 – 如果你期望基于用户input的错误,“@和error_get_last”方法对我来说似乎是非常明智的 – 我没有看到使用set_error_handler更合适。

顺便说一句,不知道如果我应该做这个@戈登的答案编辑,而不是作为一个单独的答案。 有人可以build议吗?

 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; }