title: best way to determine if a URL is an image in PHP
body: <p>Using PHP, given a URL, how can I determine whether it is an image?  </p>
  
  <p>There is no context for the URL - it is just in the middle of a plain text file, or maybe just a string on its own.</p>
  
  <p>I don't want high overhead (e.g. reading the content of the URL) as this could be called for many URLs on a page. Given this restriction, it isn't essential that all images are identified, but I would like a fairly good guess.  </p>
  
  <p>At the moment I am just looking at the file extension, but it feels like there should be a better way than this.</p>
  
  <p>Here is what I currently have:</p>
  
  <pre><code>  function isImage( $url )
    {
      $pos = strrpos( $url, ".");
      if ($pos === false)
        return false;
      $ext = strtolower(trim(substr( $url, $pos)));
      $imgExts = array(".gif", ".jpg", ".jpeg", ".png", ".tiff", ".tif"); // this is far from complete but that's always going to be the case...
      if ( in_array($ext, $imgExts) )
        return true;
      return false;
    }
  </code></pre>
  
  <p><strong>Edit:</strong> In case it's useful to anybody else here is the final function using the technique from Emil H's answer:</p>
  
  <pre><code>  function isImage($url)
    {
       $params = array('http' =&gt; array(
                    'method' =&gt; 'HEAD'
                 ));
       $ctx = stream_context_create($params);
       $fp = @fopen($url, 'rb', false, $ctx);
       if (!$fp) 
          return false;  // Problem with url
  
      $meta = stream_get_meta_data($fp);
      if ($meta === false)
      {
          fclose($fp);
          return false;  // Problem reading data from url
      }
  
      $wrapper_data = $meta["wrapper_data"];
      if(is_array($wrapper_data)){
        foreach(array_keys($wrapper_data) as $hh){
            if (substr($wrapper_data[$hh], 0, 19) == "Content-Type: image") // strlen("Content-Type: image") == 19 
            {
              fclose($fp);
              return true;
            }
        }
      }
  
      fclose($fp);
      return false;
    }
  </code></pre>