2

I'm using the last.fm API to get the recent tracks and to search albums and artists etc. When images are returned from the API, they sometimes doesn't exist. An empty URL string is easily replaced with a placeholder image, but when an image url is given and it returns a 404, that's when my problem comes in.

I tried using fopen($url, 'r') for checking if images are available, but sometimes this gives me the following error:

Warning: fopen(http://ec1.images-amazon.com/images/I/31II3Cn67jL.jpg) [function.fopen]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in file.php on line 371

Also, I don't want to use cURL, because there are a lot of images to check and it slows the website down a lot.

What would the best solution be for checking images? I'm now using the following solution:

 <img src="..." onerror='this.src="core/img/no-image.jpg"' alt="..." title="..." /> 

Is this useful?

Any help is appreciated

kendepelchin
  • 2,680
  • 2
  • 21
  • 25

5 Answers5

3

You can use getimagesize since you are dealing with images it would also return mime type of the image

   $imageInfo = @getimagesize("http://www.remoteserver.com/image.jpg");

You can also use CURL to check HTTP response code of am image or any URL

$ch = curl_init("http://www.remoteserver.com/image.jpg");
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_exec($ch);
if(curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200)
{
    // Found Image
}
curl_close($ch);
Baba
  • 94,024
  • 28
  • 166
  • 217
  • The load time of a page would be way too much if I have to check each image. – kendepelchin May 07 '12 at 21:25
  • Its faster just checking HTTP CODE .. that is why i gave that option ... multicurl also makes it 10x faster – Baba May 07 '12 at 21:28
  • Please add `curl_setopt($ch, CURLOPT_TIMEOUT, 2);` and `curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);` – Baba May 07 '12 at 21:33
  • http://stackoverflow.com/questions/10035954/php-get-all-the-images-from-url-which-width-and-height-200-more-quicker/10036599#10036599 – Baba May 07 '12 at 21:35
  • works, but I hope it will not kill my website when there are more images to load. What does the curlopt_timeout_2 do? – kendepelchin May 07 '12 at 21:36
  • Let me know if you need the multi curl version – Baba May 07 '12 at 22:12
  • I'm trying it out now with your solution. If not sufficient, I will check out the multi curl version. thanks – kendepelchin May 08 '12 at 07:07
  • I check for favicon.ico, i get no error even if this image doesn't exist: http://reseauinternational.net/favicon.ico – Gino Nov 02 '16 at 14:43
  • What if image path is private? CURLINFO_HTTP_CODE will always return 403. – sd077 Nov 14 '22 at 11:54
2
function fileExists($path){
    return (@fopen($path,"r")==true);
}

from the manual for file_exists()

2

Depending on the number of images and frequency of failures, it's probably best to stick with your current client-side approach. Also, it looks like the images are served through Amazon CloudFront - in that case, use the client-side approach because it could just be a propagation issue with a single edge server.

Applying server-side approach will be network intensive and slow (waste of resources), especially in php because you'll need to check each image sequentially.

John Himmelman
  • 21,504
  • 22
  • 65
  • 80
  • 1
    That's a great reply (just because it's gives me no more extra work, ha :)) seriously, thanks for the great approach – kendepelchin May 07 '12 at 21:26
  • 1
    I don't agree PHP is slow .... MULTI CURL + CURLOPT_NOBODY + CURLINFO_HTTP_CODE is faster – Baba May 07 '12 at 21:30
  • @Baba It's still a waste of resources (cpu, bandwidth, etc.), especially if the images are served through CloudFront. Also, it's last.fm - I'd open a support ticket and leave it to their team to resolve, it's their responsibility. – John Himmelman May 07 '12 at 21:33
  • Do you have an idea of the bandwidth that is used to check HTTP CODE ??? It might used bandwidth but not as bad as you think .. try it out your self – Baba May 07 '12 at 21:36
  • @Baba It doesn't take into account the CF issue, it could return 404 for the server, but not for the client. Any solution at this point, is just a hack/workaround. I'd take this up with last.fm. – John Himmelman May 07 '12 at 21:52
  • @JohnHimmelman it is indeed last.fm's responsibility, but opening a ticket would mean waiting till they fix it. Can't wait and I think they're not handling tickets very well... – kendepelchin May 07 '12 at 21:53
1

Also might be useful check the request headers, using get_headers php function as follows:

$url = "http://www.remoteserver.com/image.jpg";
$imgHeaders = @get_headers( str_replace(" ", "%20", $url) )[0];

if( $imgHeaders == 'HTTP/1.1 200 Ok' ) {
    //img exist
}
elseif( $imgHeaders == 'HTTP/1.1 404 Not Found' ) {
    //img doesn't exist
}
Evhz
  • 8,852
  • 9
  • 51
  • 69
  • Headers request is faster having into account that the response does not include body content. – Evhz Feb 27 '16 at 22:47
0

The following function will try to get any online resource (IMG, PDF, etc.) given by URL using get_headers, read headers and searching for string 'Not Found' in it using function strpos. If this string is found, meaning the resource given by URL is not available, this function will return FALSE, otherwise TRUE.

function isResourceAvaiable($url)
{
  return !strpos(@get_headers($url)[0],'Not Found')>0;
}
sbrbot
  • 6,169
  • 6
  • 43
  • 74