Forum Moderators: phranque
I'm somewhat new to htaccess. I realized a few months back it's crucial to good web design, and it would be wreckless not learning about it. Right now I'm aiming for cache control.
To my understanding: if a user agent it smart enough to request the last-modified header (or Etag), and there's a match, it won't d/l the file again. If htaccess is the one to provide that info, then a PHP script (if such was the file in question) won't even have to run. Right?
This is important to me because I've noticed a bare PHP script eats up 7 megs or ram. Sure php can do headers, but 7 megs is a huge overhead for something so simple.
How should I use last-modified on files with htaccess, as well as Etag if you happen to know.
Is it a good idea to put the last-mod header in a <files> tag?
ex:
<files something.htm>
Header set last-modified "Sun Jul 18 00:32:50 EDT 2004"
</files>
I can always modify the date with a php/perl script when it changes. But is there a way for htaccess check the real file mod-date?
Is these proper syntax?
<files something.htm *.html *.php whatever.pl start*end.p*p>
Would that last one require a regular expression?
Also what's the difference in using "Header set/unset/append"?
I'm pretty sure I understand them, but a proper explanation would be nice.
Thanks.
To my understanding: if a user agent it smart enough to request the last-modified header (or Etag), and there's a match, it won't d/l the file again. If htaccess is the one to provide that info, then a PHP script (if such was the file in question) won't even have to run. Right?
...snippage..
Is it a good idea to put the last-mod header in a <files> tag?
ex:
<files something.htm>
Header set last-modified "Sun Jul 18 00:32:50 EDT 2004"
</files>I can always modify the date with a php/perl script when it changes. But is there a way for htaccess check the real file mod-date?
Is these proper syntax?
<files something.htm *.html *.php whatever.pl start*end.p*p>
Would that last one require a regular expression?
<FilesMatch> can be used to construct a list using regular-expressions notation.
Back up a bit and take a look at this problem from a higher level. If you implement this solution, you will have to manually update that Last-Modified date now and forever. The potential for error is large, and it's also a maintenance headache - You will never be able to take a vacation/holiday without serving a stale file for the duration.
I'd suggest a caching solution -- either using Squid or a 'manual' approach.
A manual approach involves modifying the script to write its output to a static file, and then serving that static file. When a request arrives, you can use mod_rewrite to check for the existence of that static file. If it exists, serve it. If not, run the script again to re-create it, then serve it.
How you manage the expiration of the static file depends on your needs; You can delete the static file manually to force a regeneration -- which is again a maintenance headache. Or you can set up a cron job to delete it every so many minutes or hours. How you set up cron jobs varies by host, but look in your control panel first.
An example of the mod_rewrite code for use in /.htaccess would be:
# If static html page exists
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
# rewrite php file requests to it
RewriteRule ^(php-file)\.php$ /$1.html [L]
Jim
You can set the 'last-mod' to the filemtime() of the script and use that, combined with the 'page' requested, to generate your ETag.
This should give you the ability to keep the .php page in the server cache, while cutting down the times it executes --- make sure you exit() if there is a 304.
Personally, I use php for almost everything. One of the cool 'biproducts' of setting your .html headers with .php is you can set a blanket 'long-cache' on the files your server sends a 'header' tag with and cache graphics, css, and other files for a longer period of time, freeing additional resources normally used to process requests for 'nothing' files.
If you are trying to give the appearance of truly 'static' you may want to look into setting 'content length' also.
Justin
Edited: Can't type/communicate in English very well yet today --- It's the only language I speak, so it could be a long day. --- I'll stop editing soon Jim.
(IOW: Adjusted wording so people could read the post AND it would make a little sense.)
mod_headers is what you are currently using, though I don't understand why you need a last-modified header.. apache generates that header automatically unless its something dynamic like php.. then use something in the code to do this.. like for php:
@header ('Cache-Control: private, pre-check=0, post-check=0, max-age=1080');
@header ('Expires: ' . gmstrftime("%a, %d %b %Y %H:%M:%S GMT", time() + 1080)); //60*3
@header ('Last-Modified: ' . gmstrftime("%a, %d %b %Y %H:%M:%S GMT", time() - 20)); //60*60*3
# MONTH
<FilesMatch "\.(flv夙if夸pg夸peg如ng夷co存wf)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
# WEEK
<FilesMatch "\.(js圭ss如df宇xt)$">
Header set Cache-Control "max-age=604800"
</FilesMatch>
# DAY
<FilesMatch "\.(html多tm)$">
Header set Cache-Control "max-age=43200"
</FilesMatch>
# DONT CACHE
<FilesMatch "\.(pl如hp圭gi存pl)$">
Header set Cache-Control "max-age=0"
</FilesMatch>
It talks about using the FileETag directive
FileETag INode MTime Size
FileETag -INode
FileETag MTime Size
FileETag All
And the Files and FilesMatch directives:
Using the Files Directive<Files ~ "\.(htm¦html¦css¦js¦php)$">
AddDefaultCharset UTF-8
DefaultLanguage en-US
</Files>
Using the FilesMatch Directive (preferred)
<FilesMatch "\.(htm¦html¦css¦js¦php)$">
AddDefaultCharset UTF-8
DefaultLanguage en-US
</FilesMatch>