为了账号安全,请及时绑定邮箱和手机立即绑定

使用php输出图像

使用php输出图像

PHP
青春有我 2023-07-08 22:04:11
有一堆与此标题相同的问题。例如如何使用php输出图像?使用 PHP 输出为图像如何使用php输出图像并下载答案总是一些变化添加header('Content-type: image/jpeg');到您的代码中毫无疑问,这是答案的重要部分,但遗漏了一些我真的无法解决的重要步骤。现在,当图像位于根目录下时,使用 php 获取图像有明显的好处。假设你有一个网页<?phprequire_once("load_a_scripts.php");print("lots of html");// fetch image from below root directory and output in HTML?><img id="this_one" src="" height="200" width="200" />您想输出上面的图像 this_one 吗?PHP 可以使用 readfile() 来获取所需的文件,但这在这里并没有多大用处(最多你会得到随机的 unicode 输出,而不是这里的正确图像)。防止乱码输出的解决方案是使用这显然在这里似乎不合适。不仅有输出,这将使得设置标题变得不可能,而且即使这一操作过程成功,人们所能期望的最好的结果就是出现图像的下载提示。同样,这不是所需的功能。因此,一些解决方案建议使用一些外部代码,例如&ldquo;image.php&rdquo;,它将拥有自己的标头并获取图像,等等。然而,这又存在一些问题。image.php 如何知道您想要什么图像? <?php header('Content-Type:'.$photo); if(isset($photo)&&isset($type)){     if(strlen($photo)>15||strlen($type)>6){        die();        }    $photo = strtolower($photo);    $photo = preg_replace('/[^a-z0-9 -]+/', '', $photo);    $photo = str_replace(' ', '-', $photo);    $photo = trim($photo, '-');    $type = strtolower($type);    $type = preg_replace('/[^a-z0-9 -]+/', '', $type);    $type = str_replace(' ', '-', $type);    $type = trim($type, '-');    readfile('../img/'.$user_id.$photo);}假设可以使用 GET 发送与图像名称 ($photo) 和 mime ($type) 相关的参数,但同样,什么发送这些参数以及如何发送?一些答案似乎表明您可以直接链接到外部 image.php ,就好像它是图像一样<img src="image.php" /> 但这再次提出了一个问题:image.php 如何知道 $photo 和 $type 的值。
查看完整描述

1 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

您有两个基本选项:首先,使用外部图像加载器/处理程序脚本(例如<img src="image.php?i=sunshine.jpg" />);其次,对图像数据进行 base64 编码(例如<img src="data:image/png;base64, i26dfdXAd..." />)。第二个选项会让你的 HTML 变得臃肿,就像没有明天一样。那么让我们简单地看一下image.php处理程序方法。

处理程序如何知道要显示什么图像?它需要一个查询字符串,例如image.php?i=sunshine.jpg;或image.php?i=sunshine&x=jpg;或者image.php?i=sunshine&x=jpg&s=600,如果您想加载特定尺寸,等等。您必须在 HTML 源中使用该格式,没有脚本可以自动知道要加载什么图像。然后,发送参数的是“谁”(您),而不是“什么”。您需要确保变量得到正确的清理(正如您的示例处理程序所做的那样);与任何用户可修改的输入一样,它们不应该被信任,尤其是靠近文件系统操作(目录遍历等)的任何地方。$_GET['i']这些变量将作为、等供您的处理程序脚本使用$_GET['x']

如果您觉得 URL 参数很麻烦,或者看起来很脏,您可以随时重写 URL。将图像链接为<img src="images/sunshine.jpg" />,并.htaccess在 /images/ 文件夹(仅包含您的脚本)中设置重写规则,将所有图像请求传递到处理程序脚本。您还可以使用此方法来处理缩小的图像版本,并将源 URL<img src="images/sunshine__600.jpg" />映射到重写规则。

关于使用readfile()(脱口而出大块数据的最内存友好的方式),只要您在调用header('Content-type: image/jpeg');之前输出(或其他适当的 MIME 标头)readfile(),它就会以所需的方式工作。也就是说,浏览器不会知道网络服务器直接从文件系统提供的图像与通过处理程序从网络根外部提供的图像之间的区别。它只是带有图像 HTTP 标头的数据。


编辑:奖金。编写了一个简约的安全部署文件处理程序。

<?php

/* 

 * Receive image call as: <img src="img.php?i=name.jpg" />

 * Output matching image file from $basepath directory

 */


$basepath = '../images/'; // Path to image folder


$mimes = [ // Allowed image types:

    'jpg' => 'image/jpeg',

    'png' => 'image/png',

    'gif' => 'image/gif',

    'svg' => 'image/svg+xml',

];


!isset($_GET['i']) && die(); // Nothing to do here.


// Parse & Verify Extension

$ext = strtolower(pathinfo($_GET['i'], PATHINFO_EXTENSION));

!isset($mimes[$ext]) && die('Invalid filetype!'); // If MIME N/A: die!


// Parse & Sanitize Filename 

$file = basename($_GET['i']);

$file = preg_replace('#[^[:alnum:] ._-]#', '', $file);


$filepath = realpath($basepath . $file);

$filepath === false && die('Invalid filename!'); // If image N/A: die!


// Output MIME header and image:

header('Content-Type:' . $mimes[$ext]);

readfile($filepath);

exit;

如果您需要容纳jpeg等变体,只需 a) 复制数组中的 MIME 定义$mimes,或 b) 添加扩展规范化例程。如果您需要访问子文件夹中的图像,例如?i=sun/shine.jpg,请重新编写不带basename. (确保您不会受到目录遍历的影响!)。[:alnum:] ._-]将从请求的文件名中删除除 以外的字符。根据需要修改正则表达式。



查看完整回答
反对 回复 2023-07-08
  • 1 回答
  • 0 关注
  • 129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信