views:

510

answers:

4

How can I make a PHP script cache-friendly to our private reverse proxy (Squid)?

I would like it to stay cached for the rest of the day. In other words, the page's last modification is 00:00 today and it will expire at 00:00 tomorrow.

What are the minimum required HTTP headers to do this reliably?

EDIT: I do not want the client's browser to cache any differently. That is, I wish to retain control over purging stale pages on our Squid server at any given time.

+1  A: 

I assume you mean you want to cache the output of the script, not the script itself. And you clearly want serverside scripting so HTTP headers is not what you want (unless there is some tie-in to Squid, which there very well might be). But this isn't what Squid is designed for.

For this kind of thing, you really want memcached (or similar).

Check if the result is in the cache. If it is, return it. If not, generate the result (eg using ob_start(), etc), put it in the cache and return it.

cletus
+1  A: 

you could run your script and generate static HTML files to be served. that way, it's up to you when to replace the content.

you don't have to run your scripts inside the web server. a cron job works perfectly.

Javier
+2  A: 

@OP: Below is some commented code to achieve what you asked.

@cletus: You said memcached is what the OP wants, and that this is not what Squid is designed for.

I don't know what Squid was designed for but I know what it is used for and there are definitely people using it as a reverse proxy to take load off dynamic page generation. No "tie-in" is needed except standard HTTP headers.

I'm not sure why you're so quick to recommend memcached without knowing more about the nature of the application and environment.

<?php

// the time we got hit and generated content
$now = time();
$generatedAt = gmdate('D, d M Y H:i:s T', $now);

// the last modified date (midnight on the same day of generation, as
// per your business-rule)
$lastModified = gmdate('D, d M Y 00:00:00 T', $now);

// date of expiry (24 hours after the last modified date, as per your
// business-rule)
$expiresAt = gmdate('D, d M Y H:i:s T', strtotime($lastModified) + 86400);

// the minimum required http headers to make Squid do what you asked is
// Last-modified and Cache-control.  We need to give Cache-control the
// expiry time in terms of "age" (in seconds) so we calculate that below.
// Optionally you could also provide the "Expires: $expiresAt" header to
// tell the browser/client the same information, just in a different way.
// This is not required for Squid though.
$maxAge = strtotime($expiresAt) - strtotime($generatedAt);
header('Last-modified: ' . $lastModified);
header('Cache-control: max-age=' . $maxAge);

// The rest is simply informational
header('Content-type: text/plain');
echo "The content of this page was last modified at $lastModified\n";
echo "This page was generated at $generatedAt and will be cached by Squid for $maxAge seconds until $expiresAt\n";

// Sample output:
//
// The content of this page was last modified at Tue, 13 Jan 2009 00:00:00 GMT
// This page was generated at Tue, 13 Jan 2009 04:29:33 GMT and will be cached by Squid for 70227 seconds until Wed, 14 Jan 2009 00:00:00 GMT
A: 

Have you tried using APC ?

http://us.php.net/apc

The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. It was conceived of to provide a free, open, and robust framework for caching and optimizing PHP intermediate code.

Ram Prasad