【发布时间】:2012-09-03 14:46:35
【问题描述】:
我可以使用getimagesize() 来验证图像,但问题是如果淘气的用户将链接指向10GB random file,那么它会破坏我的生产服务器的带宽。如何限制getimagesize() 获取的文件大小? (例如,最大图像大小为 5MB)
PS:问之前我已经research了。
【问题讨论】:
标签: php validation getimagesize
我可以使用getimagesize() 来验证图像,但问题是如果淘气的用户将链接指向10GB random file,那么它会破坏我的生产服务器的带宽。如何限制getimagesize() 获取的文件大小? (例如,最大图像大小为 5MB)
PS:问之前我已经research了。
【问题讨论】:
标签: php validation getimagesize
您可以单独下载文件,设置您希望下载的最大大小:
function mygetimagesize($url, $max_size = -1)
{
// create temporary file to store data from $url
if (false === ($tmpfname = tempnam(sys_get_temp_dir(), uniqid('mgis')))) {
return false;
}
// open input and output
if (false === ($in = fopen($url, 'rb')) || false === ($out = fopen($tmpfname, 'wb'))) {
unlink($tmpfname);
return false;
}
// copy at most $max_size bytes
stream_copy_to_stream($in, $out, $max_size);
// close input and output file
fclose($in); fclose($out);
// retrieve image information
$info = getimagesize($tmpfname);
// get rid of temporary file
unlink($tmpfname);
return $info;
}
【讨论】:
stream_copy_to_stream 不会有内存问题吗?
您不想一开始就执行getimagesize('http://example.com') 之类的操作,因为这将下载图像一次,检查大小,然后丢弃下载的图像数据。 那是真正的带宽浪费。
因此,将下载过程与检查图像大小分开。例如,使用fopen打开图片URL,一点一点地读取,写入一个临时文件,记录你读了多少。一旦超过 5MB 仍未完成阅读,您将停止并拒绝该图像。
您可以在开始实际下载之前尝试读取 HTTP Content-Size 标头以清除明显较大的文件,但您不能依赖它,因为它可以被欺骗或省略。
【讨论】:
这是example,您需要进行一些更改以满足您的要求。
function getimagesize_limit($url, $limit)
{
global $phpbb_root_path;
$tmpfilename = tempnam($phpbb_root_path . 'store/', unique_id() . '-');
$fp = fopen($url, 'r');
if (!$fp) return false;
$tmpfile = fopen($tmpfilename, 'w');
$size = 0;
while (!feof($fp) && $size<$limit)
{
$content = fread($fp, 8192);
$size += 8192; fwrite($tmpfile, $content);
}
fclose($fp);
fclose($tmpfile);
$is = getimagesize($tmpfilename);
unlink($tmpfilename);
return $is;
}
【讨论】:
8192?