Why do images served from my web server not cache

2019-07-15 12:43发布

I store all of my images behind the webroot (before /var/www/), which means that the web server is unable to send cache headers back for my pictures. What do I need to add to this to make the user's web cache work? Currently, this is getting hit every time by the same browser.

My <img> path on my pages look something like this:

<img src="pic.php?u=1134&i=13513&s=0">

Edit: Could it be that it is because "pic.php?u=1134&i=13513&s=0" is not a valid file name or something?

// pic.php
<?php

    // open the file in a binary mode
    $user = $_GET['u'];
    $id = $_GET['i'];
    $s = $_GET['s'];

    if (!isset($user) && !isset($s) && $isset($id))
    {
        // display a lock!
        exit(0);
    }

    require_once("bootstrap_minimal.php"); //setup db connection, etc

    // does this image_id belong to the user?
    $stmt = $db->query('SELECT image_id, user_id, file_name, private FROM images WHERE image_id = ?', $id);
    $obj = $stmt->fetchObject();

    if (is_object($obj))
    {
        // is the picture is the users?
        if ($obj->user_id != $_SESSION['user_id'])
        {
            // is this a private picture?
            if ($obj->private == 1)
            {
                // check permissions...
                // display a lock in needed!
            }
        }
    }
    else
    {
        // display a error pic?!
        exit(0);
    }

    if ($s == 0)
    {
        $picture = $common->getImagePathThumb($obj->file_name);
    }
    else
    {
        $picture = $common->getImagePath($obj->file_name);
    }

    // send the right headers
    header("Content-Type: image/png");
    header("Content-Length: " . filesize($picture));

    $fp = fopen($picture, 'rb');

    // dump the picture and stop the script
    fpassthru($fp);
    exit;
?>

5条回答
beautiful°
2楼-- · 2019-07-15 12:57

Apache only caches static files by default. You need to send a cache control header via the header() function. This article has a lot of information on the topic.

Alternatively, you could use the PHP file to redirect to the actual location of the image. (This is probably the easiest way if you don't know anything about headers.)

查看更多
来,给爷笑一个
3楼-- · 2019-07-15 12:58

You need to add something like:

$expiry = 3600*24*7; // A week
header('Expires: ' . gmdate('D, d M Y H:i:s' time() + $expiry) . ' GMT');
header('Cache-control: private, max-age=' . $expiry);
查看更多
三岁会撩人
4楼-- · 2019-07-15 12:59

What I would do in your situation is to stream the bytes of the image using a .php file. Don't link to images directly; instead, link to a php file that: - outputs the cache headers - reads the file off of disk, from behind the webroot - sends the image bits down the wire

查看更多
淡お忘
5楼-- · 2019-07-15 13:06

Simple answer: you aren't telling your users' browser to cache it

查看更多
Rolldiameter
6楼-- · 2019-07-15 13:16

You might try:

header("Cache-Control: max-age=3600");

That should send a cache timeout of one hour on the file.

查看更多
登录 后发表回答