如何使用 PHP 检查远程文件是否存在?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/981954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can one check to see if a remote file exists using PHP?
提问by Ramon Poca
The best I could find, an iffclosefopentype thing, makes the page load really slowly.
我能找到的最好的,一种iffclosefopen类型的东西,使页面加载非常缓慢。
Basically what I'm trying to do is the following: I have a list of websites, and I want to display their favicons next to them. However, if a site doesn't have one, I'd like to replace it with another image rather than display a broken image.
基本上我想要做的是以下内容:我有一个网站列表,我想在它们旁边显示它们的网站图标。但是,如果网站没有,我想用另一张图片替换它,而不是显示损坏的图片。
回答by Ramon Poca
You can instruct curl to use the HTTP HEAD method via CURLOPT_NOBODY.
您可以通过 CURLOPT_NOBODY 指示 curl 使用 HTTP HEAD 方法。
More or less
或多或少
$ch = curl_init("http://www.example.com/favicon.ico");
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// $retcode >= 400 -> not found, $retcode = 200, found.
curl_close($ch);
Anyway, you only save the cost of the HTTP transfer, not the TCP connection establishment and closing. And being favicons small, you might not see much improvement.
无论如何,你只节省了HTTP传输的成本,而不是TCP连接的建立和关闭。由于网站图标很小,您可能看不到太大的改进。
Caching the result locally seems a good idea if it turns out to be too slow. HEAD checks the time of the file, and returns it in the headers. You can do like browsers and get the CURLINFO_FILETIME of the icon. In your cache you can store the URL => [ favicon, timestamp ]. You can then compare the timestamp and reload the favicon.
如果结果太慢,在本地缓存结果似乎是个好主意。HEAD 检查文件的时间,并在标题中返回它。您可以像浏览器一样获取图标的 CURLINFO_FILETIME。在您的缓存中,您可以存储 URL => [ favicon, timestamp ]。然后,您可以比较时间戳并重新加载网站图标。
回答by Tom Haigh
As Pies say you can use cURL. You can get cURL to only give you the headers, and not the body, which might make it faster. A bad domain could always take a while because you will be waiting for the request to time-out; you could probably change the timeout length using cURL.
正如 Pies 所说,您可以使用 cURL。你可以让 cURL 只给你标题,而不是正文,这可能会使它更快。坏域总是需要一段时间,因为您将等待请求超时;您可能可以使用 cURL 更改超时长度。
Here is example:
这是示例:
function remoteFileExists($url) {
$curl = curl_init($url);
//don't fetch the actual page, you only want to check the connection is ok
curl_setopt($curl, CURLOPT_NOBODY, true);
//do request
$result = curl_exec($curl);
$ret = false;
//if request did not fail
if ($result !== false) {
//if request was ok, check response code
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($statusCode == 200) {
$ret = true;
}
}
curl_close($curl);
return $ret;
}
$exists = remoteFileExists('http://stackoverflow.com/favicon.ico');
if ($exists) {
echo 'file exists';
} else {
echo 'file does not exist';
}
回答by luBar
CoolGoose's solution is good but this is faster for large files (as it only tries to read 1 byte):
CoolGoose 的解决方案很好,但对于大文件来说速度更快(因为它只尝试读取 1 个字节):
if (false === file_get_contents("http://example.com/path/to/image",0,null,0,1)) {
$image = $default_image;
}
回答by Mala
This is not an answer to your original question, but a better way of doing what you're trying to do:
这不是对您原始问题的回答,而是一种更好的方式来做您想做的事情:
Instead of actually trying to get the site's favicon directly (which is a royal pain given it could be /favicon.png, /favicon.ico, /favicon.gif, or even /path/to/favicon.png), use google:
与其实际尝试直接获取网站的 favicon(鉴于它可能是 /favicon.png、/favicon.ico、/favicon.gif 或什至 /path/to/favicon.png,这是一种皇家的痛苦),而是使用谷歌:
<img src="http://www.google.com/s2/favicons?domain=[domain]">
Done.
完毕。
回答by Э?ad Дьdulя?мaи
If you are dealing with images, use getimagesize. Unlike file_exists, this built-in function supports remote files. It will return an array that contains the image information (width, height, type..etc). All you have to do is to check the first element in the array (the width). use print_r to output the content of the array
如果您正在处理图像,请使用 getimagesize。与 file_exists 不同,这个内置函数支持远程文件。它将返回一个包含图像信息(宽度、高度、类型等)的数组。您所要做的就是检查数组中的第一个元素(宽度)。使用print_r输出数组的内容
$imageArray = getimagesize("http://www.example.com/image.jpg");
if($imageArray[0])
{
echo "it's an image and here is the image's info<br>";
print_r($imageArray);
}
else
{
echo "invalid image";
}
回答by CONvid19
A complete function of the most voted answer:
投票最多的答案的完整功能:
function remote_file_exists($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if( $httpCode == 200 ){return true;}
}
You can use it like this:
你可以这样使用它:
if(remote_file_exists($url))
{
//file exists, do something
}
回答by hakre
This can be done by obtaining the HTTP Status code (404 = not found) which is possible with file_get_contentsDocsmaking use of context options. The following code takes redirects into account and will return the status code of the final destination (Demo):
这可以通过获取 HTTP 状态代码(404 = 未找到)来完成,这在使用上下文选项的file_get_contentsDocs中是可能的。以下代码将重定向考虑在内,并将返回最终目的地(Demo)的状态代码:
$url = 'http://example.com/';
$code = FALSE;
$options['http'] = array(
'method' => "HEAD",
'ignore_errors' => 1
);
$body = file_get_contents($url, NULL, stream_context_create($options));
foreach($http_response_header as $header)
sscanf($header, 'HTTP/%*d.%*d %d', $code);
echo "Status code: $code";
If you don't want to follow redirects, you can do it similar (Demo):
如果你不想跟随重定向,你可以这样做(Demo):
$url = 'http://example.com/';
$code = FALSE;
$options['http'] = array(
'method' => "HEAD",
'ignore_errors' => 1,
'max_redirects' => 0
);
$body = file_get_contents($url, NULL, stream_context_create($options));
sscanf($http_response_header[0], 'HTTP/%*d.%*d %d', $code);
echo "Status code: $code";
Some of the functions, options and variables in use are explained with more detail on a blog post I've written: HEAD first with PHP Streams.
在我写的一篇博客文章中更详细地解释了一些正在使用的函数、选项和变量:HEAD first with PHP Streams。
回答by CoolGoose
if (false === file_get_contents("http://example.com/path/to/image")) {
$image = $default_image;
}
Should work ;)
应该管用 ;)
回答by Krishan Gopal
PHP's inbuilt functions may not work for checking URL if allow_url_fopensetting is set to off for security reasons.Curl is a better option as we would not need to change our code at later stage. Below is the code I used to verify a valid URL:
如果出于安全原因将allow_url_fopen设置设置为关闭,PHP 的内置函数可能无法用于检查 URL 。Curl 是一个更好的选择,因为我们不需要在后期更改我们的代码。下面是我用来验证有效 URL 的代码:
$url = str_replace(' ', '%20', $url);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($httpcode>=200 && $httpcode<300){ return true; } else { return false; }
Kindly note the CURLOPT_SSL_VERIFYPEERoption which also verify the URL's starting with HTTPS.
请注意CURLOPT_SSL_VERIFYPEER选项,它也验证以 HTTPS 开头的 URL。
回答by yckart
To check for the existence of images, exif_imagetypeshould be preferred over getimagesize, as it is much faster.
要检查图像是否存在,exif_imagetype应该优先于getimagesize,因为它要快得多。
To suppress the E_NOTICE, just prepend the error control operator (@).
要抑制E_NOTICE,只需添加错误控制运算符 ( @)。
if (@exif_imagetype($filename)) {
// Image exist
}
As a bonus, with the returned value (IMAGETYPE_XXX) from exif_imagetypewe could also get the mime-type or file-extension with image_type_to_mime_type/ image_type_to_extension.
作为奖励,我们还可以通过返回值 ( IMAGETYPE_XXX)exif_imagetype获得带有image_type_to_mime_type/的 mime 类型或文件扩展名image_type_to_extension。

