<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gabriel Crowe &#187; dynamic</title>
	<atom:link href="http://www.gabrielcrowe.co.uk/tag/dynamic/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gabrielcrowe.co.uk</link>
	<description>Web Designer, Ecommerce, Wordpress and Design for Print In Bishop Auckland</description>
	<lastBuildDate>Thu, 27 Oct 2011 12:05:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Speeding up your PHP: full page caches.</title>
		<link>http://www.gabrielcrowe.co.uk/2010/01/22/speeding-up-your-php-application-with-full-page-caches/</link>
		<comments>http://www.gabrielcrowe.co.uk/2010/01/22/speeding-up-your-php-application-with-full-page-caches/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 15:04:11 +0000</pubDate>
		<dc:creator>Gabriel Crowe</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://www.gabrielcrowe.co.uk/?p=12</guid>
		<description><![CDATA[Why cache content? Sometimes, when you are creating custom solutions in PHP, you don&#8217;t have the luxury of speedup caches in Ecommerce and CMS frameworks. The problem is that people arent always experts in database design, and SQL, so pages with messy queries in them tend to load slowly. This can lose visitors interest, and [...]]]></description>
			<content:encoded><![CDATA[<h2>Why cache content?</h2>
<p>Sometimes, when you are creating custom solutions in PHP, you don&#8217;t have the luxury of speedup caches in Ecommerce and CMS frameworks. The problem is that people arent always experts in database design, and SQL, so pages with messy queries in them tend to load slowly. This can lose visitors interest, and if its ecommerce related, sales.</p>
<p>The idea is simple. Only query the databases when the content changes. If the same content is going to be fed out all the time, then why would you waste your time re-building that content, every time something hit your page?</p>
<blockquote><p>It&#8217;ll save you money if your page gets hit a lot, and it&#8217;ll make people happier when they get your page quicker.</p></blockquote>
<p>So, we <em>keep a copy</em> of the generated page first time its looked at. Using the full url as a reference, we keep them, and when someone asks for the same page again, we give them the cached copy. It&#8217;s much faster to do this.</p>
<h2>So, lets get stuck in</h2>
<p>Create a file called &#8220;cache_header.php&#8221; containing this:</p>
<pre lang="php" line="1">
<?php
$starttime = microtime();
$startarray = explode(" ", $starttime);
$starttime = $startarray[1] + $startarray[0];
// Settings
$cachedir = 'cache/'; // Directory to cache files in (keep outside web root)
$cachetime = 600; // Seconds to cache files for
$cacheext = 'cache'; // Extension to give cached files (usually cache, htm, txt)
// Ignore List
$ignore_list = array(
'domainname.co.uk/ignorethis.php',
'domainname.co.uk/ignorethisaswell.php'
);
// Script
$page = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // Requested page
$cachefile = $cachedir . md5($page) . '.' . $cacheext; // Cache file to either load or create
$ignore_page = false;
for ($i = 0; $i < count($ignore_list); $i++) {
$ignore_page = (strpos($page, $ignore_list[$i]) !== false) ? true : $ignore_page;
}
$cachefile_created = ((@file_exists($cachefile)) and ($ignore_page === false)) ? @filemtime($cachefile) : 0;
@clearstatcache();
// Show file from cache if still valid
if (time() - $cachetime < $cachefile_created) {
ob_start('ob_gzhandler');
@readfile($cachefile);
ob_end_flush();
exit();
}
// If we're still here, we need to generate a cache file
ob_start();
?>
</pre>
<p>Then create a file called &#8220;cache_footer.php&#8221; containing:</p>
<pre lang="php" line="1">
<?php
$endtime = microtime();
$endarray = explode(" ", $endtime);
$endtime = $endarray[1] + $endarray[0];
$totaltime = $endtime - $starttime;
$totaltime = round($totaltime,5);
echo "<!-- This page took $totaltime seconds to generate -->";
// Now the script has run, generate a new cache file
$fp = @fopen($cachefile, 'w');
// save the contents of output buffer to the file
@fwrite($fp, ob_get_contents());
@fclose($fp);
ob_end_flush();
?>
</pre>
<p>in the same folder, create a folder called &#8216;cache&#8217; and set it to writable by the php, using an FTP client:</p>
<div class="wp-caption alignnone" style="width: 269px"><img title="Screenshot of permissions" src="http://www.interact-studio.co.uk/screencast/2010-01-20_1147.png" alt="Screenshot of permissions" width="259" height="140" /><p class="wp-caption-text">Screenshot of permissions</p></div>
<p>Finally, implement the cache on your dynamic page:</p>
<pre lang="php" line="1">
<? require('cache_header.php'); ?>
<?
//this is dynamic php
?>
<? require('cache_footer.php'); ?>
</pre>
<p>This effectively creates static html of a dynamic file and saves it to the cache. The cache is used if the same url is requested within a certain timeframe. This means that database intensive popular pages load instantly.</p>
<p>Good eh?</p>
<p>The real problem with this system is that it does not pay any attention to pages that are dynamically different due to logins and sessions.</p>
<p>Don&#8217;t randomly implement this on any old php software. this is a bare bones example. In order for this to work in a complex example where individuals with different credentials are likely to see different pages, you&#8217;d need to have the system aware of their credentials, and display a fresh version of the page, based on the presence of an individual. This is NOT covered in the example, and it assumes that every user gets the same page.</p>
<p>What I tend to do, is leave the main page uncached, and any elements that are custom to the user and experience uncached.</p>
<p>The included elements i will cache. For example, my popular products block, i will cache. When they are pulled into the page by the server, the server merely includes a file, instead of drawing from a database.</p>
<p>Overall this hybrid approach isnt as speedy as caching the entire page, but its very close and as a performance versus benefit tradeoff, it works very well indeed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabrielcrowe.co.uk/2010/01/22/speeding-up-your-php-application-with-full-page-caches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

