使用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;
}
型
9条答案
按热度按时间a64a0gku1#
您可以使用HTTP HEAD请求并检查内容类型。这可能是一个很好的折衷方案。它可以使用PHP Streams完成。Wez Furlong有一个article,展示了如何使用这种方法发送post请求,但它可以很容易地调整为发送HEAD请求。您可以使用stream_get_meta_data()从http响应中检索头。
当然,这并不是100%。有些服务器会发送不正确的头。但是,它会处理通过脚本发送的图像和正确的文件扩展名不可用的情况。真正确定的唯一方法是实际检索图像-要么全部,要么前几个字节,正如thomasrutter所建议的那样。
xlpyo6sf2#
字符串
6tr1vspr3#
有几种不同的方法。
字符串
像这样嗅探内容可能最适合您的需求;您只需要读取并下载文件的前几个字节(头之后)。
不幸的是,一个文件既可能是有效的图像,也可能是包含有害内容的ZIP文件,这些内容可能会被有害网站作为Java执行-参见the GIFAR exploit。您几乎可以通过将图像加载到GD等库中并对其执行一些重要的过滤器来防止此漏洞,像软化或锐化它一个微小的量(即使用卷积过滤器),并保存到一个新的文件 * 没有 * 传输任何元数据。
试图仅通过内容类型来确定某个东西是否是图像是非常不可靠的,几乎和检查文件扩展名一样不可靠。当使用<img元素加载图像时,浏览器会嗅探魔法字符串。
vd2z7a6w4#
Emil H的回答:
使用
get_headers()
检查url的内容类型,而无需使用getimagesize()
下载整个文件字符串
xcitsw885#
编辑:用于带有流行图像扩展的静态图像。
字符串
xriantvc6#
类似于某些给定的答案,但逻辑略有不同。
字符串
@是error control operator。
注意,我们在条件中使用了“严格”运算符
=== FALSE
,因为在我们的用例中,如果在干草堆中找到针,strpos($headers['Content-Type'], 'image/')
确实会返回0
。使用==
的类型转换会错误地解释为FALSE
。u7up0aaq7#
我们可以使用exif_imagetype来检查图像类型,所以它不允许任何其他内容类型。它只允许图像,我们可以将它们限制为少数图像类型,下面的示例代码显示如何允许GIF图像类型。
字符串
您可以使用以下图像类型,
型
更多详情:link
fnvucqvd8#
最简单但不是最安全的一条线:
字符串
mhd8tkvw9#
快速解决损坏或找不到图像链接
我建议你不要使用getimagesize(),因为它将第一次下载图像,然后它将检查图像的大小+如果这不会图像,那么它将抛出异常,所以使用下面的代码
字符串
**注意:**此当前代码可帮助您识别损坏或未找到的URL图像,但不会帮助您识别图像类型或标题