假设您有一个缩略图生成器脚本,它接受URL形式的源图像。有没有办法检测源URL是否“损坏” - 是否不存在或导致非图像文件?
使用getimagesize()
或其他PHP GD功能的蛮力不是解决方案,因为可能输入可能根本不是图像的欺骗性流浪URL(http://example.com/malicious.exe
或相同文件,但重命名为http://example.com/malicious.jpg
) - 这样的情况很容易被PHP检测到之前必须调用GD。在GD尝试解析文件之前,我正在寻找GD预先消毒。
作为第一步,以下正则表达式检查URL是否是图像扩展名:preg_match('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)([^\s]+(\.(?i)(jpg|png|gif|bmp))$)@', $txt,$url);
在php中使用file_exists
函数,你可以用它检查网址。
请参阅下面的文档,显示如何检查img ...您需要的确切内容
文件存在 - http://www.php.net/manual/en/function.file-exists.php#93572
URL EXISTS - http://www.php.net/manual/en/function.file-exists.php#85246
这是alternative code用于检查网址。如果你将在浏览器中测试用\n
替换<br/>
<?php
$urls = array('http://www.google.com/images/logos/ps_logo2.png', 'http://www.google.com/images/logos/ps_logo2_not_exists.png');
foreach($urls as $url){
echo "$url - ";
echo url_exists($url) ? "Exists" : 'Not Exists';
echo "\n\n";
}
function url_exists($url) {
$hdrs = @get_headers($url);
echo @$hdrs[1]."\n";
return is_array($hdrs) ? preg_match('/^HTTP\\/\\d+\\.\\d+\\s+2\\d\\d\\s+.*$/',$hdrs[0]) : false;
}
?>
输出如下
http://www.google.com/images/logos/ps_logo2.png - Content-Type: image/png
Exists
http://www.google.com/images/logos/ps_logo2_not_exists.png - Content-Type: text/html; charset=UTF-8
Not Exists
我使用以下方法来检测远程图像的属性
$src='http://example.com/image.jpg';
list($width, $height, $type, $attr) = @getimagesize($src);
示例(检查stackoverflows“职业2.0”图像)
$src='http://sstatic.net/ads/img/careers2-ad-header-so.png';
list($width, $height, $type, $attr) = @getimagesize($src);
echo '<pre>';
echo $width.'<br>';
echo $height.'<br>';
echo $type.'<br>';
echo $attr.'<br>';
echo '</pre>';
如果$ height,$ width等为null,则图像显然不是图像或文件不存在。使用cURL过度而且速度较慢(即使使用CURLOPT_HEADER)
唯一真正可靠的方法是使用file_get_contents()
请求图像,并使用getimagesize()
查找其图像类型。
只有当getimagesize()
返回有效的文件类型时,您才能依赖它实际上是一个有效的图像。
不过,这非常耗费资源。
您可以考虑根本不进行任何服务器端检查,并将onerror
JavaScript事件添加到已完成的图像资源:
<img src="..." onerror="this.style.display = 'none'">
try for local files
<?php
if(file_exists($filename))
{
//do what you want
}
else
{
//give error that file does not exists
}
?>
对于外部域
$headers = @get_headers($url);
if (preg_match("|200|", $headers[0])) {
// file exists
} else {
// file doesn't exist
}
您也可以使用curl请求。
破解或未找到图像链接的快速解决方案 我建议你不要使用getimagesize(),因为它将首先下载图像,然后它将检查图像大小+如果这将不会成像然后它将抛出异常所以使用下面的代码
if(checkRemoteFile($imgurl))
{
//found url, its mean
echo "this is image";
}
function checkRemoteFile($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
// don't download content
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if(curl_exec($ch)!==FALSE)
{
return true;
}
else
{
return false;
}
}
注意:此当前代码可帮助您识别损坏或未找到的URL图像,这无助于您识别图像类型或标题
在将实际图像放入生成器之前,您可以检查HTTP响应的HTTP status code(应该是200)和Content-type header(图像/ png等)。
如果这两个前提条件都没问题,那么在检索图像后,您可以在其上调用getimagesize()
,看它是否中断,返回的MIME类型等等。
你尝试过file_get_contents()方法吗?
如果加载图像时发生错误,请执行JavaScript:
如果在加载外部文件(例如文档或图像)时发生错误,则触发onerror事件。
例:
<!DOCTYPE html>
<html>
<body>
<img src="image.gif" onerror="myFunction()">
<p>A function is triggered if an error occurs when loading the image. The function shows an alert box with a text.
In this example we refer to an image that does not exist, therefore the onerror event occurs.</p>
<script>
function myFunction() {
alert('The image could not be loaded.');
}
</script>
</body>
</html>