想象一下:
<img src="/image.php?image=5.jpg" />
现在,在image.php
:
header('content-type: image/jpeg');
$image = imagecreatefromjpeg($_GET['image']);
imagejpeg($image,NULL,100);
这样可行,但这样脚本会加载图像,处理它,然后回显它。这可以在不处理图像的情况下完成吗?
我想这样做的原因是我不希望人们知道图像的位置,因此我不想将完整路径写入img
src属性。
我只需要将原始图像发送到浏览器,但不会泄露其真实位置。
答案 0 :(得分:12)
是的,你可以。只需readfile
而不是imagecreatefromXXX
+ imagejpeg
。
header('Content-Type: image/jpeg');
$src = /* process $_GET['image'] to recover the path */;
readfile($src);
/* process $_GET['images'] to recover the path */
部分意味着您需要对输入进行任何清理,以避免有人请求禁止的文件。如果您的脚本输入是文件路径,这可能意味着从预定义列表中检查,剥离可能的目录分隔符,检查正则表达式等。另一种方法是将路径存储在数据库中并将脚本传递给一个简单的id,并且用它恢复文件路径。这可能是一个更好的主意,因为用户将看不到脚本URL上的任何文件路径(如果您只是传递路径,人们实际上可以猜测文件的位置,这就是您要阻止的内容)。
答案 1 :(得分:10)
当然,使用readfile
。不要忘记限制允许的图像名称。否则,您将创建一个directory traversal漏洞。
header('content-type: image/jpeg');
$img = preg_replace('/[^0-9a-z\._\-]/', '_', $_GET['image']);
readfile($img);
答案 2 :(得分:2)
如http://www.php.net/manual/en/function.readfile.php
之类的内容来自示例
<?php
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>