Posts Tagged ‘PHP’

Caching of PHP scripts with query strings

Saturday, January 10th, 2009

Trying to decrease bandwith usage and page loading time, I’ve enabled caching on some of my web pages recently. Caching can be done in many ways, and with PHP-scripts running on Apache, I have the choice of enabling caching in either .htaccess-files, in the HTML-header or in the HTTP header. I think sending HTTP headers from PHP gives the best control, having all programatically possibilities for conditional caching and headers.

For basic caching of a generated PHP-page I find the “Expires” / “max-age” HTTP headers the most convenient to use;


//Cache for 15 minutes:
$maxage = 60*15;
header ("Cache-Control: max-age=$maxage");
header ('Expires: ' . gmstrftime("%a, %d %b %Y %H:%M:%S GMT", time() + $maxage));

With this method, the page will be loaded from the user’s browser-cache instead of from my server until $maxage seconds have passed. After that, a new visit to the page will be freshly loaded from my server to the browser’s cache again, and will live there for another $maxage seconds. This works well with URLs such as

  • http://www.example.com/index.php
  • http://www.example.com/index.html
  • http://www.example.com/
  • http://www.example.com/pages/frontpage/

but not with URLs containing query strings:

http://www.example.com/index.php?page=frontpage&itemcount=10

The problem with query strings

If the URL to the page in question contains a query string (starting with the question mark in this URL: http://www.example.com/index.php?page=frontpage&itemcount=10), the HTTP standard says that the browser never should cache that page. Using standard-compliant browsers like Opera, you’ll have to get rid of that query string to enable caching of such pages.

I long scratched my head over this, but was after a while enlightened by Cal Henderson’s post:

According the letter of the HTTP caching specification, user agents should never cache URLs with query strings. While Internet Explorer and Firefox ignore this, Opera and Safari don’t – to make sure all user agents can cache your resources, we need to keep query strings out of their URLs.

Getting rid of the query string – URL rewriting

URL rewriting can be used to tricking the browser into believing we’re browsing an ordinary page without query strings. URL rewriting means that the user and the user’s browser enters and sees an URL like http://www.example.com/frontpage.asdf, while the Apache web server internally translates this to, let’s say, http://www.example.com/index.php?page=frontpage, running your index.php script with the right GET parameters.

Using Apache, this is as easy as writing some RewriteRules in a .htaccess-file, for instance:

RewriteEngine On

#do not rewrite requests for /index.php:
RewriteRule ^index.php$ - [L]

#rewrite /frontpage.asdf, /photos.asdf
#to /index.php?page=frontpage etc:
RewriteRule ^(.*?).asdf$ /index.php?page=$1 [QSA,L]

More tips and tricks about URL rewriting can be read here and many other places. Google it!

preg_replace in PHP with /e flag

Wednesday, September 17th, 2008

The /e flag makes the (quoted) replacement string to be treated as PHP-code, so that one can make more complex regex-replacements in a one-liner.

An example: I want to search for a pattern in a string, and replace any occurences with an array element whose key/index equals the occurence.

Without the /e flag this wouldn’t be as easy, because this does not work;


$pattern = '/\{(.*?)\}/i';
$outputline = preg_replace($pattern, $array[\\1], $inputline); //doesn't make any sense

With the /e flag, however, this works like a charm;


$pattern = '/\{(.*?)\}/ei'; //note the /e flag
$outputline = preg_replace($pattern, '$array[\\1]', $inputline); //works with /e flag

This replaces occurences of $pattern in $inputline with $array[OccurenceOfPatternInInputline] and assigns the result to $outputline.