缓存php服务的图像

时间:2017-07-20 15:32:49

标签: php mysql session caching

我试图像这样通过php提供图像:

img.php

<?php
session_start();
$file=$images_path.$_GET['id'].".jpg";
$lastModified = gmdate('D, d M Y H:i:s', filemtime($file)) . ' GMT';
header("Cache-Control: private");
header("Content-type: image/jpeg");
header("ETag: ".md5_file($file));
header("Last-Modified: $lastModified");
header('Expires: ' . gmdate("D, d M Y H:i:s", ((60*60*24*1)+strtotime($lastModified))));//1 day expire

$db=new PDO("mysql:host=".$host.";dbname=".$db_name,$db_user,$db_psw);

$e=explode("/",$_GET['id']);
$post=$e[0];
$e=explode("_",$e[1]);
$user=$e[0];

$q="SELECT p.id FROM post p INNER JOIN files f ON p.id=f.post WHERE p.id=".$post." AND ";
if(!isset($_SESSION['id'])) $q.="p.privacy=1";
else
{
    $q.="(";
    $q.="p.user=".$_SESSION['id'];
    $q.=" OR p.privacy=1";
    $q.=" OR (p.privacy=2 AND p.user IN (".$_SESSION['id'];
    if(count($_SESSION['friends'])>0) $q.=",".implode(",",array_keys($_SESSION['friends']));
    $q.="))";
    $q.=" OR ".$_SESSION['id']." IN(SELECT tag FROM tags WHERE post=p.id)";
    $q.=")";
}
$q.=" AND f.user=".$user." AND (f.date IS NOT NULL"; if(isset($_SESSION['id'])) $q.=" OR f.user=".$_SESSION['id']; $q.=")";
$q.=" LIMIT 1";
$sql=$db->prepare($q); $sql->execute(); $post=$sql->fetch(PDO::FETCH_ASSOC);
if(!isset($post['id'])) {header("location:".$localhost); exit;}

if(file_exists($file))
{
    header('Content-Type:image/jpeg');
    readfile($file);
}
?>

的index.php

<img src="img.php?id=1/1_1"><br>
<img src="img.php?id=1/1_2"><br>
<img src="img.php?id=1/1_3"><br>

但它很慢,并且没有缓存图像,我该怎么办?

由于

更新1

好的readfile(),我修好了

我更新了完整代码,这是必需的,因为我服务的图片不在公共根文件夹中,我必须检查当前登录用户是否有权使用会话查看图像mysql查询

更新2

我想要: 如果files.date为NULL,则不要缓存图像,或者将其缓存并在更改时强制重新加载 如果files.date IS NOT NULL,则永远缓存图像 我不知道我应该使用哪些标题以及

更新3

以下是图片标题的屏幕截图 screenshot

更新4

如果资源被缓存,我想避免查询执行,那么使用会话变量来缓存图像的URL呢?

3 个答案:

答案 0 :(得分:0)

这是一种非常奇怪的显示文件的方式。您不需要fopen()该文件。只需回显每个文件的路径,然后让客户端直接下载文件。

然后应自动进行缓存。

答案 1 :(得分:0)

尝试使用readfile(),因为它只需一个简单的移动即可读取和发送文件。

session_start();
/*connecting db*/
/*query for checking images privacy through session user*/
header('Content-Type:image/jpeg');
readfile($_GET['id']);
  

但是,如果大部分时间都是在阅读数据库并检查安全性的情况下,这可能不会那么有用。在这种情况下,也许您应该向我们展示代码,可能有一些方法可以加快速度。

答案 2 :(得分:0)

您不需要PHP脚本来返回带有GET参数的文件。您可以在<img>元素中生成路径并让其静态提供:

<img src="<?php echo $id; ?>">

如果由于某种原因你还需要从PHP返回图像,那么快速流回来的最好方法是使用readfile

header('Content-Type:image/jpeg');
readfile($_GET['id']);

虽然您应该首先验证GET参数是一个良好的图像路径以确保安全性。否则,您可能会冒险将服务器上的其他文件返回给客户端。

如果您未在会话中检查任何内容,则无需启动会话即可返回文件。

既然我们看到了更多代码并且您需要数据库调用,我接下来建议设置标头以指示浏览器在给定时间内缓存图像。适当的时间范围取决于更新查询数据的频率。根据您的需要设置cache-control and possibly other headers

除此之外,您必须找到提高数据库/查询性能的方法或完全避免使用服务器端缓存的查询。