Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

cache friendliness and HTTP_IF_MODIFIED_SINCE

Posted on 2004-08-04
24
Medium Priority
?
430 Views
Last Modified: 2012-06-27
I have a PHP script that displays images. For a number of reasons I wanted the images not to be readily available through http, so I did a simple script to serve them.

This is TOTALY bad to cache, images get reloaded at every visit.

btw, these images never change, so once they are read they are there!

The problem is that

echo $_SERVER['HTTP_IF_MODIFIED_SINCE']';

returns nothing.

is it a problem of the apache configuration??

am I just dumb?

BTW, the images never change, so it would be even simpler than usual!

what should I do to save bandwidth?

0
Comment
Question by:frox
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 7
  • 4
  • +3
24 Comments
 
LVL 36

Accepted Solution

by:
Zyloch earned 600 total points
ID: 11715759
If-Modified-Since is not a predefined PHP header, and it's a request header, so it'll be useless for you. You can try this:

<?php
header('Cache-Control: only-if-cached');
?>

Regards,
${Zyloch}
0
 
LVL 33

Expert Comment

by:snoyes_jw
ID: 11715800
>problem of the apache configuration??
Possible, but let's explore other avenues first

>am I just dumb?
See above comment.

>what should I do to save bandwidth?
Have you tried using session_cache_limiter("public")?

http://us3.php.net/manual/en/function.session-cache-limiter.php
0
 
LVL 16

Expert Comment

by:hankknight
ID: 11715873
This isn't quite what you asked for, but it might be what you need.

Apache's mod_rewrite allows you to make a PHP script look like an image to a browser.

Put this in your .htaccess file:
      RewriteEngine on
      RewriteRule ^(.*).jpg  script_that_returns_image.php?image=$1 [NE]

If your are getting the image now through
       /script_that_returns_image.php?image=smile

the code provided would allow you to call the image by the following URL:
       /smile.jpg


That way, the browser can't tell the difference, and you can still control the output through PHP.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:frox
ID: 11715939
For Zyloch:

I tried this

<?php
header('Cache-Control: only-if-cached');
echo time();
?>

But anytime I open the page I see the seconds changed.
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 11716001
only-if-cached tells a proxy to send its cached copy if it has it. You should try, like snoyes_jw has said, to use session_cache_limiter("public") which allows the user's machine to cache.
0
 

Author Comment

by:frox
ID: 11716005
For  snoyes_jw:

Also

<?php
session_cache_limiter("public");
echo time();
?>

still shows the seconds that change.

0
 
LVL 36

Expert Comment

by:Zyloch
ID: 11716014
Overall, it depends on whether the user ends up caching the images or not. The headers sent are only to allow it to. You could, of course, find a free webhost online that has unlimited bandwidth and allows hotlinking, but that's about all I can think of.
0
 

Author Comment

by:frox
ID: 11716091
I am sorry, I still don't get it.

What I would want to do is that if the user refreshes (even with F5) the script of the page gets refreshed as usual, but the scripts of the images do NOT get reloaded, i.e. they behave as normal images.

(will be away for 20 mins)
0
 
LVL 33

Expert Comment

by:snoyes_jw
ID: 11716112
I assume that the point of this question is to avoid people linking to your images from other sites.  It might be simpler to just serve the images as normal, and use .htaccess to prevent hotlinks.
http://altlab.com/htaccess_tutorial.html
0
 

Author Comment

by:frox
ID: 11716160
to snoyes_jw:
>  I assume that the point of this question is to avoid people
> linking to your images from other sites
No, it's to control access of users to images, in any situation, not just to avoid hotlinking.
0
 
LVL 2

Expert Comment

by:TaintedGod
ID: 11716627
> but the scripts of the images do NOT get reloaded, i.e. they behave as normal images.

Scripts of images? What are you talking about and what exactly is normal?

>No, it's to control access of users to images...

What sort of control are you talking about then?
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 11716997
When the user reloads your site, the images will be reloaded no matter what. There's no way to stop that. Use .htaccess to set a password on the file.
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 11717002
The image files I mean.
0
 

Author Comment

by:frox
ID: 11717041

>> but the scripts of the images do NOT get reloaded, i.e. they behave as normal images.
>Scripts of images? What are you talking about and what exactly is normal?

Sorry for crappy english!

The script of the page is a script that says something like this:

======== index.php ========
...
<body>
<img src="logo.gif">
<?
 echo "This is your image";
 echo "<img src="image.php"'>";
?>
</body>
...

The script of the image is something like this
======== image.php ========
...
  $filename="somewhere.gif";
  $size = getimagesize ($filename);
  $fp = fopen($filename, 'rb');
  header("Content-type: {$size['mime']}");
  fpassthru($fp);
  exit;
...

What I want is that when the user reloads (presses F5) index.php gets reloaded, but image.php does not get reloaded (just like logo.gif does not get reloaded)

this means image.php must be able to say "Status: 304 not modified" or what's the exact command

I hope this was more clear :-)
0
 
LVL 27

Assisted Solution

by:Diablo84
Diablo84 earned 600 total points
ID: 11717122
you could try

header("HTTP/1.0 304 Not Modified");

in image.php

ie.

  $filename="somewhere.gif";
  $size = getimagesize ($filename);
  $fp = fopen($filename, 'rb');
  header("Content-type: {$size['mime']}");
  header("HTTP/1.0 304 Not Modified");
  fpassthru($fp);
  exit;
0
 

Author Comment

by:frox
ID: 11717130
Zyloch:
> the images will be reloaded
No, IMHO the images are reloaded if you press Shift-F5 (or something similar, depends on browsers)
the "default" reload will not reload images if tyour browser and the server are on the fact that the image has not changed.

0
 

Author Comment

by:frox
ID: 11717176
Diablo84
> header("HTTP/1.0 304 Not Modified");

mmhh. you mean ALWAYS say that the contents has not changed, even if I do not know if it's in the users' cache??

That seems risky. I would be doing something VERY unexpected for the browsers, saynig them "as usual" even if they don't have the image.
0
 
LVL 27

Expert Comment

by:Diablo84
ID: 11717212
The image file has to be downloaded once before the browser will have the header information so in theory it will do as you want, if the file has not beenn downloaded the browser wont have the header information.

The only issue i can see is if the image loading in image.php is dynamic in which case the purpose of the whole question is somewhat defeated.
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 11717219
Are you trying to put all our header suggestions in the image script file or the main file?
0
 

Author Comment

by:frox
ID: 11717225
What I  found at http://www.phpbuilder.com/columns/brunner20011113.php3?page=3 is:


1) see if it's newer that the browser already has
if ($HTTP_IF_MODIFIED_SINCE == $gmt_mtime) {
   header("HTTP/1.1 304 Not Modified");
   exit;
}

2) otherwise send the contents but first inform the browser of the modification date
$lastmod_header = "Last-Modified: " . $gmt_mtime;
Header($lastmod_header);
....

For static files (ex. .GIF) this is automagically handled by apache.

for php this is left to us.
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 11717274
You can try this:

$gmtTime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
$allheaders = getallheaders();
if ($allheaders['If-Modified-Since'] == $gmtTime) {
   header("HTTP/1.1 304 Not Modified");
   exit;
}
0
 

Author Comment

by:frox
ID: 11717278
Diablo84:
> The only issue i can see is if the image loading in image.php is dynamic
well in this case, saying  "not modified" would be a blatant lie!

Anyway, I will give a fast try to your aproach.

Zyloch:
>Are you trying to put all our header suggestions in the image script file or the main file?
No, the main file can stay as it is.
It's the images that I want to give proper headers (at the current rate, I would exceed 100GB per month, no host will support this without asking money! :-)

0
 
LVL 27

Expert Comment

by:Diablo84
ID: 11717311
another possibility i just thought of is setting the header expiration date in the future

eg.

$time = time() + 3600;
$gtime = gmdate('D, d M Y H:i:s', $time) . ' GMT';
header("Expires: $gtime");


3600 in this line is 3600 seconds

$time = time() + 3600;

obviously modify this for the amount of time you want to set it ahead
0
 
LVL 27

Expert Comment

by:Diablo84
ID: 11717343
for example you could set the expiration dates a week ahead so it would (again, in theory) only download the images once a week

$time = time() + 604800;
$gtime = gmdate('D, d M Y H:i:s', $time) . ' GMT';
header("Expires: $gtime");
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
3 proven steps to speed up Magento powered sites. The article focus is on optimizing time to first byte (TTFB), full page caching and configuring server for optimal performance.
The viewer will learn how to dynamically set the form action using jQuery.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

670 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question