如何检查使用PHP是否存在远程文件?

我能find的最好的, if fclose fopentypes的东西,使页面加载真的很慢。

基本上我想要做的是以下几点:我有一个网站列表,我想显示他们的favicons旁边。 但是,如果一个网站没有一个,我想用另一个图像replace而不是显示一个破碎的图像。

您可以指示curl通过CURLOPT_NOBODY使用HTTP HEAD方法。

或多或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); 

无论如何,你只节约了HTTP传输的开销,而不是TCP连接的build立和closures。 而作为小图标,你可能没有看到太多的改善。

如果结果太慢,在本地caching结果似乎是一个好主意。 HEAD检查文件的时间,并将其返回到标题中。 您可以像浏览器一样来获取图标的CURLINFO_FILETIME。 在caching中,您可以存储URL => [favicon,timestamp]。 然后,您可以比较时间戳并重新加载图标。

馅饼说你可以使用cURL。 你可以得到cURL只给你头,而不是身体,这可能会使它更快。 一个坏域可能总是需要一段时间,因为你会等待请求超时; 你可以用cURL改变超时时间。

这里是例子:

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

CoolGoose的解决scheme是好的,但这对于大文件来说更快(因为它只尝试读取1个字节):

 if (false === file_get_contents("http://example.com/path/to/image",0,null,0,1)) { $image = $default_image; } 

这不是你原来的问题的答案,而是一个更好的方法来做你想做的事情:

而不是实际试图直接获取网站的图标(这是一个皇室的痛苦,因为它可能是/favicon.png,/favicon.ico,/ favicon.gif,甚至/path/to/favicon.png),使用谷歌:

 <img src="http://www.google.com/s2/favicons?domain=[domain]"> 

完成。

如果您正在处理图像,请使用getimagesize。 与file_exists不同,这个内置函数支持远程文件。 它将返回一个包含图像信息(宽度,高度,types等)的数组。 你所要做的就是检查数组中的第一个元素(宽度)。 使用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"; } 
 if (false === file_get_contents("http://example.com/path/to/image")) { $image = $default_image; } 

应该工作;)

这可以通过获取使用上下文选项的file_get_contents Docs可能获得的HTTP状态代码(404 =未find)来完成。 以下代码将redirect考虑在内,并将返回最终目标( 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"; 

如果你不想遵循redirect,你可以做类似( 演示 ):

 $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"; 

在我写的一篇博客文章中更详细地解释了一些正在使用的函数,选项和variables: HEAD首先使用PHP Streams 。

由于安全原因,如果allow_url_fopen设置为off,PHP的内置函数可能无法检查URL。 curl是一个更好的select,因为我们不需要在后期更改我们的代码。 以下是我用来validation有效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; } 

请注意CURLOPT_SSL_VERIFYPEER选项,它也validationURL以HTTPS开头。

一个彻底的解决办法是将图标显示为默认图标上方的div中的背景图像。 这样,所有的开销将被放置在客户端上,同时仍然不显示破碎的图像(在所有浏览器AFAIK中忽略丢失的背景图像)。

答案最多的完整curlfunction:

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

你可以像这样使用它:

 if(remote_file_exists($url)) { //file exists, do something } 
 function remote_file_exists($url){ return(bool)preg_match('~HTTP/1\.\d\s+200\s+OK~', @current(get_headers($url))); } $ff = "http://www.emeditor.com/pub/emed32_11.0.5.exe"; if(remote_file_exists($ff)){ echo "file exist!"; } else{ echo "file not exist!!!"; } 

您可以使用 :

 $url=getimagesize(“http://www.flickr.com/photos/27505599@N07/2564389539/”); if(!is_array($url)) { $default_image =”…/directoryFolder/junal.jpg”; } 

您可以使用以下内容:

 $file = 'http://mysite.co.zahttp://img.dovov.comfavicon.ico'; $file_exists = (@fopen($file, "r")) ? true : false; 

在尝试检查URL上是否存在图像时为我工作

您应该发出HEAD请求,而不是GET请求,因为根本不需要URI内容。 正如馅饼所述,你应该检查状态码(在200-299范围内,你可以select跟随3xxredirect)。

答案的问题包含了很多可能有用的代码示例: PHP / Curl:HEAD请求在某些站点上需要很长时间

还有一个更复杂的select。 你可以使用JQuery技巧来检查所有的客户端。

 $('a[href^="http://"]').filter(function(){ return this.hostname && this.hostname !== location.hostname; }).each(function() { var link = jQuery(this); var faviconURL = link.attr('href').replace(/^(http:\/\/[^\/]+).*$/, '$1')+'/favicon.ico'; var faviconIMG = jQuery('<img src="favicon.png" alt="" />')['appendTo'](link); var extImg = new Image(); extImg.src = faviconURL; if (extImg.complete) faviconIMG.attr('src', faviconURL); else extImg.onload = function() { faviconIMG.attr('src', faviconURL); }; }); 

http://snipplr.com/view/18782/add-a-favicon-near-external-links-with-jquery/ (原来的博客是目前下来)

所有使用get_headers()的答案都在做GET请求。 做一个HEAD请求会更快/更便宜。

为了确保get_headers()做一个HEAD请求,而不是一个GET,你应该添加这个:

 stream_context_set_default( array( 'http' => array( 'method' => 'HEAD' ) ) ); 

所以要检查一个文件是否存在,你的代码看起来像这样:

 stream_context_set_default( array( 'http' => array( 'method' => 'HEAD' ) ) ); $headers = get_headers('http://website.com/dir/file.jpg', 1); $file_found = stristr($headers[0], '200'); 

$ file_found显然会返回false或true。

为了检查图像的存在, exif_imagetype应该优于getimagesize ,因为它更快。

要抑制E_NOTICE ,只需预先安装错误控制运算符( @ )。

 if (@exif_imagetype($filename)) { // Image exist } 

作为奖励,利用来自exif_imagetype的返回值( IMAGETYPE_XXX ),我们也可以得到带有image_type_to_mime_type / image_type_to_extension的mimetypes或文件扩展名。

当文件不存在时,不知道这个文件是否更快, is_file() ,但你可以试试 。

 $favIcon = 'default FavIcon'; if(is_file($remotePath)) { $favIcon = file_get_contents($remotePath); }