Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: caching pages with state

Tags:

php

caching

I would like to utilize caching on a couple pages:

  1. individual blog pages
  2. index.php

However, after devising my system, I realized that the headers of my pages change according to state very slightly (aka, it says something like "Hello, [email protected]" if you are signed in). I therefore want to make sure that it doesn't accidentally display the wrong username or email up top.

It's a shame that such a small thing that I would like to NOT be cached on a page should force me to cache nothing on my site at all.

How can I get around this?

like image 375
johnnietheblack Avatar asked Feb 19 '10 21:02

johnnietheblack


3 Answers

You'll want to think about WHY you want to do caching. Caching is an optimisation and as such, should only be done if necessary.

If you aren't sure it's necessary, go back and do some research to make sure. This will involve performance testing on production-grade hardware on your test lab.

Once you're sure it is necessary, then you will know how much improvement you need. You can consider caching just PARTS of pages - this will be less efficient on the front-end and caching layer than caching complete pages, but may take more load off the back-end as you will get a higher cache hit rate.

Consider a page which has a personalised element (say, Hello Johnnie) and a part which is expensive to compute but changes relatively infrequently and is the same for all users - say some stock prices.

You can cache the stock prices part of the page for (say) 5 minutes and generate the personalised part of the page each time. That way you don't hit your back end for stock prices and can still show the right page to the right people.

Most companies find that generating the front-end is quite computationally expensive (sticking HTML together is sadly rather time-consuming) BUT scales very well - this means that you can simply add more tin when it's not fast enough. On the other hand, back-end servers can do a lot more work, but scale much less well - e.g. databases - you cannot simply add more servers because there are consistency / synchronisation problems to contend with which limit scalability.

like image 166
MarkR Avatar answered Nov 12 '22 12:11

MarkR


A possibility I've used a couple of times is to :

  • generate the page and store it into the cache, containing something like "Hello, %%PLACEHOLDER_NAME%%" instead of the real name.
  • when a user loads the page :
    • load the cached page
    • do a (quick) str_replace to replace the %%PLACEHOLDER_NAME%% tag by the user's name
    • send the "partially dynamic" page you've creaeted this way.

It means you'll have to do some PHP manipulations, and can't cache the whole page nor serve it as a static file...

... But it also means that almost the whole page will be in cache -- you won't have to do any database query, for instance, if the name is stored in session.

(Some will say it's a bit "dirty" -- but it works really well when there is only one or two small portions that have to be dynamic, which seems to be the case, in your situation)


And if you, one day, start having "too many" of those placeholders, you'll have to consider not caching the page, but the data that are needed to generate the page.

It means you'll have to fetch the data from cache and glue them together to generate the page -- but, this way, you'll still avoid some number of SQL queries, as most of your data will be loaded from cache.

like image 4
Pascal MARTIN Avatar answered Nov 12 '22 12:11

Pascal MARTIN


You can use User Specific Parameters as the Cache_ID or Cache_ID_Key used in most Cache Libraries out there:

example:

$id = sh1($userMail);
$cache->save($id);

This is a minimal example. The idea is "the key should include user specific information", that is unique to each user.

Hope you get the idea.

like image 2
Andreas Avatar answered Nov 12 '22 14:11

Andreas