Php 文件\u获取\u内容或readfile以显示文件系统映像

Php 文件\u获取\u内容或readfile以显示文件系统映像,php,function,Php,Function,有谁能告诉我,显示文件系统中存储的图像的最佳PHP函数是什么?file\u get\u contents或readfile。我们正在从显示存储在数据库中的图像切换,因此我们仍然需要通过PHP文件调用图像,并且不能直接链接到文件系统。我见过有人推荐这两种功能,但我倾向于使用readfile。如果您对此有任何意见,我将不胜感激。我将采取以下措施: header('Content-type: image/jpeg'); readfile('something.jpg'); 在这方面似乎更有用,因为它

有谁能告诉我,显示文件系统中存储的图像的最佳PHP函数是什么?
file\u get\u contents
readfile
。我们正在从显示存储在数据库中的图像切换,因此我们仍然需要通过PHP文件调用图像,并且不能直接链接到文件系统。我见过有人推荐这两种功能,但我倾向于使用
readfile
。如果您对此有任何意见,我将不胜感激。

我将采取以下措施:

header('Content-type: image/jpeg');
readfile('something.jpg');

在这方面似乎更有用,因为它读取文件并将其写入输出缓冲区,返回从文件读取的字节数,或者错误为false。

如果不需要操作图像(调整大小、添加水印等),则最好将文件直接写入输出缓冲区。将把文件读入内存-大文件需要大量内存。

我应该使用 使用fopen,您可以更精确地处理错误


PS:请确保文件系统的直接输出不易受攻击

在编写这样的脚本时,一定要将缓存考虑在内

当在下一次页面访问中重新请求映像时,为静态映像提供服务的Web服务器将与客户端进行协商,如果服务器确定客户端的映像缓存副本仍然有效,则不会重新传输映像

由于naive脚本不执行此协商,因此图像将在每次页面请求时重新传输到客户端,这会使您的带宽大大增加

这有三种机制。我不能确切地告诉您如何编写最佳脚本,因为我以前从来没有这样做过,我也不确定不同的缓存头如何互操作以及在哪个HTTP版本上互操作,但我鼓励您进一步研究这个问题

我知道的三种机制:

过期(HTTP/1.0)

最简单的一个。此标头告诉客户端,在给定时刻之前,图像肯定是有效的。在这段时间过去之前,客户端甚至不会对脚本执行请求,因此适当地设置此选项可以节省服务器上的CPU周期和web应用中的图像加载延迟

您应该如何设置它完全取决于您的应用程序;你的图像变化是快还是少?如果映像在发送给客户端的时间到期之前更改,客户端将看不到新映像

例如:

header("Expires: " . gmdate('D, d-M-Y H:i:s \G\M\T', time() + 60)); // Valid for a minute
(注意:在HTTP/1.1中,Expires似乎已被缓存控制取代)

如果自起修改(HTTP/1.1)

如果HTTP/1.1客户端已经有映像的副本,则可以发送此标头,并记录副本的日期。然后,您可以在数据库中确定映像的当前版本是在较早的时间还是以后更改的。如果客户机的版本仍然正确,只需发送“304 Not Modified”响应并退出即可(从而避免传输图像)

例如:

$cache_time   = parse_browsers_date_time_format($_SERVER["IF-MODIFIED-SINCE"]);
$actual_time  = get_current_resource_time_from_db();

if ($actual_time <= $cache_time) {
    header("HTTP/1.1 304 Not Modified");
    die;
}

// ... Produce and output resource here
$cache\u time=parse\u browsers\u date\u time\u格式($\u SERVER[“IF-MODIFIED-SINCE”]);
$actual_time=从_db()获取_current_resource_time_;

如果($actual\u time
file\u get\u contents()
是将文件内容读入字符串的首选方式。如果操作系统支持,它将使用内存映射技术来提高性能。但除此之外,我不知道什么更好。您可以试着看看大型文件是否可以通过
file\u get\u contents()提供更好的性能
,但我认为网络流量比服务器文件IO更重要。而
readfile()
通过在
头()中传递
内容类型来下载文件

fpassthru对fopen的文件处理程序也做了同样的处理。今天我们一直在研究这个问题,感谢所有的想法。在过去的几个小时里,我一直在尝试在php脚本中指定输出图像的过期头,最后通过
头(“HTTP/1.1 304未修改”)解决了这个问题
我不完全理解强制
不修改
的含义,但是图像在下次加载时加载得更快,所以它必须工作。Stefan,如果文件很小(40 kb),但太多怎么办?仍然是文件_get_contents()更好的选择?取决于你想做什么。