I'm writing a view that will have daily/weekly/monthly report data. I'm thinking it makes sense to only run a query periodically to update the data rather than hit the database whenever someone loads the page. Can this be done completely in PHP and MySQL? What are some robust ways to handle this?
Using a templating engine like Smarty that supports caching, you can set a long cache time for those pages. You then need to code your PHP to test whether your date constraints have changed and if the data is not already cached, and if either of those conditions is true, perform the query. Otherwise, Smarty will just load the cached page and your code won't query the database.
$smarty = new Smarty();
if (!$smarty->isCached('yourtemplate.tpl')) {
// Run your query and populate template variables
}
$smarty->display('yourtemplate.tpl');
Yes but not very well. You want to look into Cron jobs, most Web hosts provide a service to setup Crons. They are simply a way to run a script, any script, PHP, Javascript, a whole page etc.
Search google for cron jobs, you should find what you're looking for.
If your web host doesn't provide cron jobs and you don't know how Unix commands work, then there are sites that will host a cron job for you.
Check out
I'm thinking it makes sense to only run a query periodically to update the data rather than hit the database whenever someone loads the page
Personally I'd go with both. e.g.
SELECT customer, COUNT(orders.id), SUM(order_lines.value)
FROM orders, order_lines
WHERE orders.id=order_lines.order_id
AND orders.placed>@last_time_data_snapshotted
AND orders.customer=@some_user
GROUP BY customer
UNION
SELECT user, SUM(rollup.orders), SUM(rollup.order_value)
FROM rollup
WHERE rollup.last_order_date<@last_time_data_snapshotted
AND rollup.customer=@some_user
GROUP BY customer
rather than hit the database whenever someone loads the page
Actually, depending on the pattern of usage this may make a lot of sense. But that doesn't necessary preclude the method above - just set a threshold on when you'll push the aggregated data into the pre-consolidated table and test the threshold on each request.
I'd personally go for the storing the cached data in a file, then just read that file if it has been updated within a certain timeframe, if not then do your update (e.g. getting info from the database, writing to the file).
Some example code:
$cacheTime = 900; // 15 minutes
$useCache = false;
$cacheFile = './cache/twitter.cachefile';
// check time
if(file_exists($cacheFile)){
$cacheContents = file_get_contents($cacheFile);
if((date('U')-filemtime($cacheFile))<$cacheTime || filesize($cacheFile)==0){
$useCache = true;
}
}
if(!$useCache){
// get all your update data setting $cacheContents to the file output. I'd imagine using a buffer here would be a good idea.
// update cache file contents
$fh = fopen($cacheFile, 'w+');
fwrite($fh, $cacheContents);
fclose($fh);
}
echo $cacheContents;