当前位置:  开发笔记 > 编程语言 > 正文

确定URL是否是PHP中的图像的最佳方法

如何解决《确定URL是否是PHP中的图像的最佳方法》经验,为你挑选了5个好方法。

使用PHP,给定URL,我如何确定它是否是图像?

URL没有上下文 - 它只是在纯文本文件的中间,或者可能只是一个字符串.

我不希望高开销(例如,读取URL的内容),因为可以在页面上调用许多URL.鉴于这种限制,所有图像都不是必需的,但我想要一个相当不错的猜测.

目前我只是在查看文件扩展名,但感觉应该有比这更好的方法.

这是我目前拥有的:

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

编辑:如果它对其他任何人有用,最后的功能是使用Emil H的答案:

  function isImage($url)
  {
     $params = array('http' => array(
                  'method' => '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;
  }

Emil H.. 28

您可以使用HTTP HEAD请求并检查内容类型.这可能是一个很好的妥协.它可以使用PHP Streams完成.Wez Furlong有一篇文章展示了如何使用这种方法发送帖子请求,但它可以很容易地适应发送HEAD请求.您可以使用stream_get_meta_data()从http响应中检索标头.

当然这不是100%.有些服务器发送错误的标头 但是,它将处理通过脚本传送图像并且没有正确的文件扩展名的情况.真正确定的唯一方法是实际检索图像 - 全部或者前几个字节,如thomasrutter所建议的那样.



1> Emil H..:

您可以使用HTTP HEAD请求并检查内容类型.这可能是一个很好的妥协.它可以使用PHP Streams完成.Wez Furlong有一篇文章展示了如何使用这种方法发送帖子请求,但它可以很容易地适应发送HEAD请求.您可以使用stream_get_meta_data()从http响应中检索标头.

当然这不是100%.有些服务器发送错误的标头 但是,它将处理通过脚本传送图像并且没有正确的文件扩展名的情况.真正确定的唯一方法是实际检索图像 - 全部或者前几个字节,如thomasrutter所建议的那样.


我喜欢检查内容类型的想法,但我也会考虑你的观点,即内容类型可能并不总是准确的.`$ headers = get_headers($ url,1); $ type = $ headers ["Content-Type"];`

2> Pedro Soares..:
if(is_array(getimagesize($urlImg)))
    echo 'Yes it is an image!';


getimagesize()下载整个图像文件.

3> thomasrutter..:

有几种不同的方法.

通过在文件开头查找幻数来嗅探内容.例如,GIF使用GIF87或GIF89作为文件的前五个字节(在ascii中).不幸的是,如果图像中存在错误或图像包含恶意内容,则无法告诉您.以下是各种类型图像文件的幻数(可随意使用):

"\xff\xd8\xff" => 'image/jpeg',
"\x89PNG\x0d\x0a\x1a\x0a" => 'image/png',
"II*\x00" => 'image/tiff',
"MM\x00*" => 'image/tiff',
"\x00\x00\x01\x00" => 'image/ico',
"\x00\x00\x02\x00" => 'image/ico',
"GIF89a" => 'image/gif',
"GIF87a" => 'image/gif',
"BM" => 'image/bmp',

嗅探这样的内容可能最符合您的要求; 你只需要阅读并因此下载文件的前几个字节(通过标题).

使用GD库加载图像以查看它是否加载而没有错误.这可以告诉您图像是否有效,没有错误.不幸的是,这可能不符合您的要求,因为它需要下载完整的图像.

如果你真的不想对图像发出HTTP请求,那么这会排除嗅探和获取HTTP头.但是,您可以尝试根据链接的上下文确定某个图像是否为图像.在

不幸的是,文件既可以是有效图像,也可以是包含有害内容的ZIP文件,可以由有害网站作为Java执行 - 请参阅GIFAR漏洞.您几乎可以肯定通过将图像加载到像GD这样的库中并对其执行一些非平凡的过滤器来防止此漏洞,例如软化或锐化它(即使用卷积滤镜)并将其保存到新文件而不传输任何元数据.

试图通过单独的内容类型确定某些内容是否是图像是非常不可靠的,几乎与检查文件扩展名一样不可靠.使用



4> RafaSashi..:

除了Emil H的回答:

使用get_headers()来检查URL的内容类型,而无需下载整个文件,getimagesize()

    $url_headers=get_headers($url, 1);

    if(isset($url_headers['Content-Type'])){

        $type=strtolower($url_headers['Content-Type']);

        $valid_image_type=array();
        $valid_image_type['image/png']='';
        $valid_image_type['image/jpg']='';
        $valid_image_type['image/jpeg']='';
        $valid_image_type['image/jpe']='';
        $valid_image_type['image/gif']='';
        $valid_image_type['image/tif']='';
        $valid_image_type['image/tiff']='';
        $valid_image_type['image/svg']='';
        $valid_image_type['image/ico']='';
        $valid_image_type['image/icon']='';
        $valid_image_type['image/x-icon']='';

        if(isset($valid_image_type[$type])){

            //do something

        }
    }



5> TheMonkeyKin..:

编辑:适用于具有常用图像扩展名的静态图像


推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有