<?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>Dougal Campbell&#039;s geek ramblings &#187; Development</title>
	<atom:link href="http://dougal.gunters.org/blog/category/development/feed" rel="self" type="application/rss+xml" />
	<link>http://dougal.gunters.org</link>
	<description>WordPress, web development, and world domination.</description>
	<lastBuildDate>Wed, 21 Jul 2010 12:00:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
	<atom:link rel='hub' href='http://dougal.gunters.org/?pushpress=hub'/>
		<item>
		<title>Unit testing in PHP with SimpleTest</title>
		<link>http://dougal.gunters.org/blog/2009/01/13/php-unit-testing?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
		<comments>http://dougal.gunters.org/blog/2009/01/13/php-unit-testing#comments</comments>
		<pubDate>Tue, 13 Jan 2009 19:40:48 +0000</pubDate>
		<dc:creator>Dougal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[code testing]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[simpletest]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[test driven development]]></category>
		<category><![CDATA[unit testing]]></category>
		<category><![CDATA[unit tests]]></category>

		<guid isPermaLink="false">http://dougal.gunters.org/?p=1362</guid>
		<description><![CDATA[<p><img class="alignright size-full wp-image-1369" title="simpletest-logo" src="http://dougal.gunters.org/wordpress/wp-content/uploads/2009/01/simpletest-logo1.png" alt="simpletest-logo" width="150" /></p>
<p>I recently worked on a <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> project which required me to write a suite of unit tests to verify that the code worked as expected. While I&#8217;ve done unit testing before, and I knew that it was valuable, I have to admit that I&#8217;ve only used it very rarely. I&#8217;ve only had a few jobs/projects that <em>required</em> it, and most other projects didn&#8217;t want to pay for the extra time.<br />
<span id="more-1362"></span><br />
Of the <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> test suites I saw, I selected <a href="http://simpletest.org/">SimpleTest</a>, as it appears to still be actively developed. [...]</p>


Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2008/11/10/wordpress-iphone-app-beta-testing' rel='bookmark' title='Permanent Link: WordPress iPhone App beta testing'>WordPress iPhone App beta testing</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/05/03/testing-a-new-spam-blocker' rel='bookmark' title='Permanent Link: Testing a new spam blocker'>Testing a new spam blocker</a></li>
<li><a href='http://dougal.gunters.org/blog/2003/01/20/pingback-testing' rel='bookmark' title='Permanent Link: Pingback Testing'>Pingback Testing</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-1369" title="simpletest-logo" src="http://dougal.gunters.org/wordpress/wp-content/uploads/2009/01/simpletest-logo1.png" alt="simpletest-logo" width="150" /></p>
<p>I recently worked on a <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> project which required me to write a suite of unit tests to verify that the code worked as expected. While I&#8217;ve done unit testing before, and I knew that it was valuable, I have to admit that I&#8217;ve only used it very rarely. I&#8217;ve only had a few jobs/projects that <em>required</em> it, and most other projects didn&#8217;t want to pay for the extra time.<br />
<span id="more-1362"></span><br />
Of the <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> test suites I saw, I selected <a href="http://simpletest.org/">SimpleTest</a>, as it appears to still be actively developed. It&#8217;s based on JUnit, as are many testing suites. You create groups of tests as classes which inherit from the UnitTestCase class. Each class contains methods, which in turn establish assertions (which are the actual states that you need to test). In each test, you call out to the functions of your own code, and compare the returned value to the value that you <em>expect</em> to get back. You test these with assertion functions like &#8216;assertEqual&#8217;, &#8216;assertTrue&#8217;, &#8216;assertIsA&#8217;, &#8216;assertIdentical&#8217;, etc. You can test equality, data types, boolean true/false, and other states.</p>
<p>As an example, let&#8217;s say you were writing a class for manipulating complex numbers. Our class handles complex numbers as tuples, so &#8217;5 &#8211; 3i&#8217; is represented by an array [5, -3]. If we were testing our &#8216;add&#8217; and &#8216;multiply&#8217; methods, you might write the tests like so:</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require</span><span class="br0">&#40;</span><span class="st0">&#39;complexnumbers-class.php&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require</span><span class="br0">&#40;</span><span class="st0">&#39;simpletest/autorun.php&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">class</span> TestComplex <span class="kw2">extends</span> UnitTestCase <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">var</span> <span class="re1">$complex</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">function</span> __construct<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">complex</span> <span class="sy0">=</span> <span class="kw2">new</span> Complex<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; parent<span class="sy0">::</span>__construct<span class="br0">&#40;</span><span class="st0">&#39;Complex Number Tests&#39;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">function</span> testComplexAdd<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$x</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">2</span><span class="sy0">,</span> <span class="nu0">5</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// 2 + 5i</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$y</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span><span class="nu0">-3</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// 1 &#8211; 3i</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$z</span> <span class="sy0">=</span> <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">complex</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="re1">$x</span><span class="sy0">,</span> <span class="re1">$y</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// should return 3 + 2i</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">assertIdentical</span><span class="br0">&#40;</span> <span class="re1">$z</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">3</span><span class="sy0">,</span> <span class="nu0">2</span><span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">function</span> test ComplexMultiply<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$x</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">2</span><span class="sy0">,</span> <span class="nu0">5</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$y</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">-3</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$z</span> <span class="sy0">=</span> <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">complex</span><span class="sy0">-&gt;</span><span class="me1">mul</span><span class="br0">&#40;</span><span class="re1">$x</span><span class="sy0">,</span> <span class="re1">$y</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// should return 17 &#8211; 1i</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">assertIdentical</span><span class="br0">&#40;</span> <span class="re1">$z</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">17</span><span class="sy0">,</span> <span class="nu0">-1</span><span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>When you run the tests, you get a report back, and if any of the tests fail, it tells you which ones. Then you go back and adjust your code, and re-test until all tests succeed.</p>
<p>The SimpleTest web site espouses Test Driven Development (TDD), where you write your tests before you develop your application, then you keep developing your code until all your tests pass. In my case, I had already written my code. And while I tend to break my code down into many &#8216;blackbox&#8217; functions, and I try to minimize global variables, I ended up refactoring my code a good bit before I was done.</p>
<p>A lot of the code I write is procedural, as opposed to object oriented (or functional, but that&#8217;s a whole other animal). It&#8217;s really just a bad habit of mine, because I learned to program before most people had ever heard of <acronym title='Object Oriented Programming'><span class='caps'>OOP</span></acronym>. It&#8217;s not that writing procedural code is inherently bad, but it is quick-and-dirty, and I do find that organizing things into a class encourages me to think harder (and better) about how things should fit together.</p>
<p>While developing my tests, I ended up converting my procedural code into a class. SimpleTest can test against any set of functions, not just classes, but I quickly decided that turning my function library into a class would be better, so that I could get rid of the need for global variables. This particular code needs to read in an external configuration file, and I had hard-coded the filename and location. To properly test all the nooks and crannies of my code, I had to refactor the code so that I could reset the configuration file. This was an improvement over my original approach. Unit testing also turned up a couple of bugs in some functionality that I hadn&#8217;t had a chance to test by other means.</p>
<p>All in all, I&#8217;d have to say that unit testing my code was a positive experience. I think I&#8217;m going to try the TDD approach next time I start a personal project, and see how it affects my development. I&#8217;ll have to change how I look at things a little bit, but I think it will probably be worth the effort.</p>
<p>Do you create unit tests, or do you just wing it? Do you develop first, then create tests, or do you use the TDD &#8216;test first&#8217; approach?</p>


<p>Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2008/11/10/wordpress-iphone-app-beta-testing' rel='bookmark' title='Permanent Link: WordPress iPhone App beta testing'>WordPress iPhone App beta testing</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/05/03/testing-a-new-spam-blocker' rel='bookmark' title='Permanent Link: Testing a new spam blocker'>Testing a new spam blocker</a></li>
<li><a href='http://dougal.gunters.org/blog/2003/01/20/pingback-testing' rel='bookmark' title='Permanent Link: Pingback Testing'>Pingback Testing</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://dougal.gunters.org/blog/2009/01/13/php-unit-testing/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Atlanta PHP</title>
		<link>http://dougal.gunters.org/blog/2008/04/02/atlanta-php?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
		<comments>http://dougal.gunters.org/blog/2008/04/02/atlanta-php#comments</comments>
		<pubDate>Wed, 02 Apr 2008 15:42:16 +0000</pubDate>
		<dc:creator>Dougal</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Atlanta]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[iis]]></category>
		<category><![CDATA[meeting]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[presentations]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">http://dougal.gunters.org/?p=901</guid>
		<description><![CDATA[<p>Tomorrow night, I will be attending the April <a href="http://www.atlantaphp.org/">Atlanta <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym></a> meeting. My friend <a href="http://blogs.msdn.com/glengordon">Glen Gordon</a> will be giving a presentation titled, &#8220;<a href="http://www.atlantaphp.org/archive/77">I&#8217;m a <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> dev! Why should I care about Microsoft?</a>&#8221;</p>
<blockquote><p>There are a host of technologies and tools from Microsoft that can add value to your <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> solutions, save you time, and are just plain cool. [...]</p></blockquote>


Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2009/12/16/im-speaking-at-wordcamp-atlanta' rel='bookmark' title='Permanent Link: I&#8217;m speaking at WordCamp Atlanta'>I&#8217;m speaking at WordCamp Atlanta</a></li>
<li><a href='http://dougal.gunters.org/blog/2010/01/09/wordcamp-atlanta' rel='bookmark' title='Permanent Link: WordCamp Atlanta'>WordCamp Atlanta</a></li>
<li><a href='http://dougal.gunters.org/blog/2010/06/15/the-business-of-wordpress-conference-atlanta' rel='bookmark' title='Permanent Link: The Business of WordPress Conference (Atlanta)'>The Business of WordPress Conference (Atlanta)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Tomorrow night, I will be attending the April <a href="http://www.atlantaphp.org/">Atlanta <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym></a> meeting. My friend <a href="http://blogs.msdn.com/glengordon">Glen Gordon</a> will be giving a presentation titled, &#8220;<a href="http://www.atlantaphp.org/archive/77">I&#8217;m a <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> dev! Why should I care about Microsoft?</a>&#8221;</p>
<blockquote><p>There are a host of technologies and tools from Microsoft that can add value to your <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> solutions, save you time, and are just plain cool. This presentation will cover server technologies like FastCGI, <acronym title='Internet Infomation Server'><span class='caps'>IIS</span></acronym> and the <acronym title='Php Hypertext Processor'><span class='caps'>PHP</span></acronym> <acronym title='Structured Query Language'><span class='caps'>SQL</span></acronym> Server Driver, client technologies like the ASP.NET <acronym title='Asynchronous Javascript and XML'><span class='caps'>AJAX</span></acronym> Library and Silverlight, as well as developer tools. This is not a sales pitch â€“ itâ€™s a technical walkthrough with demos, and will give you pointers to lots of resources for digging deeper.</p></blockquote>
<p>I&#8217;m sure Glen&#8217;s talk will be interesting, and I&#8217;m looking forward to a chance to catch up on the current state of web servers in Microsoft-land. While I tend to use unix-based systems for most of my own work, there are plenty of organizations who are standardized on Microsoft products, and you have to be able to be able to work with what they have. Case in point, my wife is hoping to set up a WordPress website for her department at work, and they&#8217;ll probably set it up on a Windows-based server.</p>
<p>If anybody reading this is planning to attend, please introduce yourself. I&#8217;ll be wearing a <a href="http://wordpress.org/">WordPress</a> shirt.</p>


<p>Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2009/12/16/im-speaking-at-wordcamp-atlanta' rel='bookmark' title='Permanent Link: I&#8217;m speaking at WordCamp Atlanta'>I&#8217;m speaking at WordCamp Atlanta</a></li>
<li><a href='http://dougal.gunters.org/blog/2010/01/09/wordcamp-atlanta' rel='bookmark' title='Permanent Link: WordCamp Atlanta'>WordCamp Atlanta</a></li>
<li><a href='http://dougal.gunters.org/blog/2010/06/15/the-business-of-wordpress-conference-atlanta' rel='bookmark' title='Permanent Link: The Business of WordPress Conference (Atlanta)'>The Business of WordPress Conference (Atlanta)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://dougal.gunters.org/blog/2008/04/02/atlanta-php/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 8: Progress!</title>
		<link>http://dougal.gunters.org/blog/2008/03/06/internet-explorer-8-progress?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
		<comments>http://dougal.gunters.org/blog/2008/03/06/internet-explorer-8-progress#comments</comments>
		<pubDate>Thu, 06 Mar 2008 15:35:26 +0000</pubDate>
		<dc:creator>Dougal</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Standards]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[forwardcompatibility]]></category>
		<category><![CDATA[futureproof]]></category>
		<category><![CDATA[ie8 ie7]]></category>
		<category><![CDATA[InternetExplorer]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[pleasesirmayihaveanother]]></category>
		<category><![CDATA[webstandards]]></category>

		<guid isPermaLink="false">http://dougal.gunters.org/?p=888</guid>
		<description><![CDATA[<p>
It seems that Microsoft has reversed their previous decision to make Internet Explorer 8 crippled by default. They will be enabling the <a href="http://blogs.msdn.com/ie/archive/2008/03/03/microsoft-s-interoperability-principles-and-ie8.aspx">standards compliant mode by default in IE8</a>, and webmasters will have to use the <code>X-UA-Compatible</code> header to force it into <acronym title='Internet Explorer 7'><span class='caps'>IE7</span></acronym> mode, for sites that can&#8217;t be updated immediately. Huzzah for progress!
</p>
<p>
And on that note, I&#8217;ll mention that <a href="http://www.microsoft.com/windows/products/winfamily/ie/ie8/default.mspx">Internet Explorer 8 Beta 1 is available for download</a>. [...]</p>


Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2008/01/23/ie8-for-better-and-worse' rel='bookmark' title='Permanent Link: Internet Explorer 8: This is progress?'>Internet Explorer 8: This is progress?</a></li>
<li><a href='http://dougal.gunters.org/blog/2003/11/07/one-pc-multiple-versions-of-internet-explorer' rel='bookmark' title='Permanent Link: One PC, Multiple Versions of Internet Explorer'>One PC, Multiple Versions of Internet Explorer</a></li>
<li><a href='http://dougal.gunters.org/blog/2006/02/02/att-chairman-loses-brain' rel='bookmark' title='Permanent Link: AT&amp;T Chairman Loses Brain, Misunderstands Internet'>AT&amp;T Chairman Loses Brain, Misunderstands Internet</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>
It seems that Microsoft has reversed their previous decision to make Internet Explorer 8 crippled by default. They will be enabling the <a href="http://blogs.msdn.com/ie/archive/2008/03/03/microsoft-s-interoperability-principles-and-ie8.aspx">standards compliant mode by default in IE8</a>, and webmasters will have to use the <code>X-UA-Compatible</code> header to force it into <acronym title='Internet Explorer 7'><span class='caps'>IE7</span></acronym> mode, for sites that can&#8217;t be updated immediately. Huzzah for progress!
</p>
<p>
And on that note, I&#8217;ll mention that <a href="http://www.microsoft.com/windows/products/winfamily/ie/ie8/default.mspx">Internet Explorer 8 Beta 1 is available for download</a>. Go break the web!</p>


<p>Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2008/01/23/ie8-for-better-and-worse' rel='bookmark' title='Permanent Link: Internet Explorer 8: This is progress?'>Internet Explorer 8: This is progress?</a></li>
<li><a href='http://dougal.gunters.org/blog/2003/11/07/one-pc-multiple-versions-of-internet-explorer' rel='bookmark' title='Permanent Link: One PC, Multiple Versions of Internet Explorer'>One PC, Multiple Versions of Internet Explorer</a></li>
<li><a href='http://dougal.gunters.org/blog/2006/02/02/att-chairman-loses-brain' rel='bookmark' title='Permanent Link: AT&amp;T Chairman Loses Brain, Misunderstands Internet'>AT&amp;T Chairman Loses Brain, Misunderstands Internet</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://dougal.gunters.org/blog/2008/03/06/internet-explorer-8-progress/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 8: This is progress?</title>
		<link>http://dougal.gunters.org/blog/2008/01/23/ie8-for-better-and-worse?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
		<comments>http://dougal.gunters.org/blog/2008/01/23/ie8-for-better-and-worse#comments</comments>
		<pubDate>Wed, 23 Jan 2008 14:25:25 +0000</pubDate>
		<dc:creator>Dougal</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Standards]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[forwardcompatibility]]></category>
		<category><![CDATA[futureproof]]></category>
		<category><![CDATA[ie7]]></category>
		<category><![CDATA[ie8]]></category>
		<category><![CDATA[InternetExplorer]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[pleasesirmayihaveanother]]></category>
		<category><![CDATA[Stupid]]></category>
		<category><![CDATA[wasp]]></category>
		<category><![CDATA[webstandards]]></category>

		<guid isPermaLink="false">http://dougal.gunters.org/blog/2008/01/23/ie8-for-better-and-worse</guid>
		<description><![CDATA[<p>
<a href="http://blogs.msdn.com/ie/archive/2007/12/19/internet-explorer-8-and-acid2-a-milestone.aspx">Internet Explorer 8 passes the Acid2 test</a>. Huzzah!
</p>
<p>
But waitaminnit&#8230; What&#8217;s this stuff about forward compatibility by adding some <a href="http://blogs.msdn.com/ie/archive/2008/01/21/compatibility-and-ie8.aspx">new <code>X-UA-Compatible</code> header</a> to my pages or my server? Am I reading this right? Are you telling me that in order for IE8 to use its fully compliant rendering, we have to add something new to our pages? And that if we don&#8217;t, it will fall back to rendering pages just like <acronym title='Internet Explorer 7'><span class='caps'>IE7</span></acronym>? Is that what this means?
</p>
<p>
That&#8217;s just dumb.
</p>
<p>
Screw their stupid &#8220;<a href="http://blogs.msdn.com/ie/archive/2008/01/21/compatibility-and-ie8.aspx">don&#8217;t break the web</a>&#8221; motto. [...]</p>


Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2008/03/06/internet-explorer-8-progress' rel='bookmark' title='Permanent Link: Internet Explorer 8: Progress!'>Internet Explorer 8: Progress!</a></li>
<li><a href='http://dougal.gunters.org/blog/2003/11/07/one-pc-multiple-versions-of-internet-explorer' rel='bookmark' title='Permanent Link: One PC, Multiple Versions of Internet Explorer'>One PC, Multiple Versions of Internet Explorer</a></li>
<li><a href='http://dougal.gunters.org/blog/2006/02/02/att-chairman-loses-brain' rel='bookmark' title='Permanent Link: AT&amp;T Chairman Loses Brain, Misunderstands Internet'>AT&amp;T Chairman Loses Brain, Misunderstands Internet</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://blogs.msdn.com/ie/archive/2007/12/19/internet-explorer-8-and-acid2-a-milestone.aspx">Internet Explorer 8 passes the Acid2 test</a>. Huzzah!
</p>
<p>
But waitaminnit&#8230; What&#8217;s this stuff about forward compatibility by adding some <a href="http://blogs.msdn.com/ie/archive/2008/01/21/compatibility-and-ie8.aspx">new <code>X-UA-Compatible</code> header</a> to my pages or my server? Am I reading this right? Are you telling me that in order for IE8 to use its fully compliant rendering, we have to add something new to our pages? And that if we don&#8217;t, it will fall back to rendering pages just like <acronym title='Internet Explorer 7'><span class='caps'>IE7</span></acronym>? Is that what this means?
</p>
<p>
That&#8217;s just dumb.
</p>
<p>
Screw their stupid &#8220;<a href="http://blogs.msdn.com/ie/archive/2008/01/21/compatibility-and-ie8.aspx">don&#8217;t break the web</a>&#8221; motto. Break it! <strong>Break the web in the name of progress!</strong> How will we ever move forward if you keep dragging us back? And while you&#8217;re at it, quit trying to misdirect us with that &#8220;don&#8217;t break the web&#8221; nonsense. Putting out a browser with excellent <acronym title='Cascading Style Sheets'><span class='caps'>CSS</span></acronym> support is not &#8220;breaking the web&#8221;, it&#8217;s fixing it! There&#8217;s no real shame in putting out a <em>better</em> product, and admitting that the previous versions had flaws. This is a concept called &#8220;continuous incremental improvement&#8221;.
</p>
<p>
There has already been a lot of reaction from the web development community. There are <a href="http://alistapart.com/articles/beyonddoctype">several</a> <a href="http://alistapart.com/articles/fromswitchestotargets">big</a> <a href="http://www.zeldman.com/2008/01/22/in-defense-of-version-targeting/">names</a> behind the idea. There are <a href="http://annevankesteren.nl/2008/01/ie-lock-in">several</a> <a href="http://ejohn.org/blog/meta-madness/">big</a> <a href="http://www.isolani.co.uk/blog/standards/EndOfLineInternetExplorer">names</a> against it. I&#8217;m not a big name, but I fall in the latter camp. This is not &#8220;forward compatibility&#8221;, it&#8217;s not &#8220;forward&#8221; anything. This is keeping progress of the Internet Explorer browser and adoption of better standards at a crawl instead of letting them make an evolutionary jump.
</p>
<p>Oh, and unless I&#8217;m missing something here, there was already a mechanism in place that the <acronym title='Internet Explorer'><span class='caps'>IE</span></acronym> team has <em>already</em> encouraged web developers to use, which could do the same job: <a href="http://blogs.msdn.com/ie/archive/2005/10/12/480242.aspx">conditional comments</a>. What&#8217;s that? Oh yeah, <a href="http://www.webstandards.org/2005/11/03/ie7-conditional-comments/">there are problems with that, too</a>.</p>
<p>
If you need more reading material on this subject, check out <a href="http://del.icio.us/wearehugh/pleasesirmayihaveanother">Mark Pilgrim&#8217;s links</a>. At the time of this writing, he has pointers to 29 articles, and I&#8217;m sure there will be more.</p>


<p>Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2008/03/06/internet-explorer-8-progress' rel='bookmark' title='Permanent Link: Internet Explorer 8: Progress!'>Internet Explorer 8: Progress!</a></li>
<li><a href='http://dougal.gunters.org/blog/2003/11/07/one-pc-multiple-versions-of-internet-explorer' rel='bookmark' title='Permanent Link: One PC, Multiple Versions of Internet Explorer'>One PC, Multiple Versions of Internet Explorer</a></li>
<li><a href='http://dougal.gunters.org/blog/2006/02/02/att-chairman-loses-brain' rel='bookmark' title='Permanent Link: AT&amp;T Chairman Loses Brain, Misunderstands Internet'>AT&amp;T Chairman Loses Brain, Misunderstands Internet</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://dougal.gunters.org/blog/2008/01/23/ie8-for-better-and-worse/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>14+ Awesome WordPress-powered sites</title>
		<link>http://dougal.gunters.org/blog/2007/07/16/14-awesome-wordpress-powered-sites?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
		<comments>http://dougal.gunters.org/blog/2007/07/16/14-awesome-wordpress-powered-sites#comments</comments>
		<pubDate>Mon, 16 Jul 2007 14:54:37 +0000</pubDate>
		<dc:creator>Dougal</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Business]]></category>
		<category><![CDATA[CrowdFavorite]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Sites]]></category>
		<category><![CDATA[Themes]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">http://dougal.gunters.org/blog/2007/07/16/14-awesome-wordpress-powered-sites</guid>
		<description><![CDATA[<div style="text-align:center;width:468px;margin:0 auto;"><a href="http://www.woothemes.com/amember/go.php?r=26427&#038;i=b44"><img src="http://dougal.gunters.org/wordpress/wp-content/uploads/2007/07/468x60c.jpg" border=0 alt="WooThemes - WordPress themes for everyone" width=468 height=60/></a></div>
<div class="pull-quote">
<a href="http://www.welovewp.com/"><img src="/pics/welovewp.com.png" alt="[A screenshot of welovewp.com]" /></a>
<p>WeLoveWP.com highlights great looking WordPress sites, and it&#8217;s powered by WordPress, too!</p>
</div>
<p>
From time to time, someone will hear that I&#8217;m involved with <a href="http://wordpress.org/">WordPress,</a> and ask me a few questions about it. [...]</p>


Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2003/09/09/powered-by-wordpress' rel='bookmark' title='Permanent Link: Powered by WordPress'>Powered by WordPress</a></li>
<li><a href='http://dougal.gunters.org/blog/2009/01/14/awesome-spam-filtering-for-wordpress' rel='bookmark' title='Permanent Link: Awesome spam filtering for WordPress'>Awesome spam filtering for WordPress</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/09/22/css-powered-slashdot-goes-live' rel='bookmark' title='Permanent Link: CSS-powered Slashdot goes live'>CSS-powered Slashdot goes live</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div style="text-align:center;width:468px;margin:0 auto;"><a href="http://www.woothemes.com/amember/go.php?r=26427&#038;i=b44"><img src="http://dougal.gunters.org/wordpress/wp-content/uploads/2007/07/468x60c.jpg" border=0 alt="WooThemes - WordPress themes for everyone" width=468 height=60></a></div>
<div class="pull-quote">
<a href="http://www.welovewp.com/"><img src="/pics/welovewp.com.png" alt="[A screenshot of welovewp.com]" /></a></p>
<p>WeLoveWP.com highlights great looking WordPress sites, and it&#8217;s powered by WordPress, too!</p>
</div>
<p>
From time to time, someone will hear that I&#8217;m involved with <a href="http://wordpress.org/">WordPress,</a> and ask me a few questions about it. Some people already have a WordPress-powered site (either self-hosted, or on <a href="http://wordpress.com/">wordpress.com</a>), and some have never actually used it, but they&#8217;ve heard of it. Often, they just want me to show them a WordPress site, so they can see what it looks like. Occasionally, someone will ask whether any big companies or famous people use WordPress. And one thing I often hear is along the lines of, <q>it just does weblogs, if I have a business site, I&#8217;d want to use something else, right?</q> But in reality, WordPress is an excellent tool for managing a business site. When I tell people this, they&#8217;ll often ask me for some examples of non-blog sites using WordPress.
</p>
<p>
So I end up searching for old bookmarks, looking through my feed archives, and checking the <a href="http://codex.wordpress.org/">Codex</a> until I find some suitable choices. Likewise, if someone just wants to see some examples of WP sites, I want to show them something that really stands out.
</p>
<p>
Now I&#8217;m finally going to document a really nice selection of sites that I can point them to for several examples, a sort of &#8220;Best of WordPress&#8221;. Some sites just look good. Some are examples of famous celebrities, companies, or organizations. Others showcase WP in a non-blog capacity. In no particular order, here is my list of <strong>Awesome WordPress Sites</strong>:
</p>
<p><span id="more-823"></span></p>
<ul>
<li>Alex King&#8217;s <a href="http://crowdfavorite.net/">Crowd Favorite</a> not only has great design, but is a perfect example of using WordPress to power a business site.</li>
<li>And Crowd Favorite, in turn, is responsible for <a href="http://allthingsd.com/">All Things Digital</a>, which is powered by <a href="http://mu.wordpress.org/">WordPress-MU</a>. Alex also has a great series of articles about <a href="http://alexking.org/blog/2006/11/02/building-v2-part1">building a customized WP site</a>.</li>
<li><a href="http://chickspeak.com/">ChickSpeak</a> is another WordPress-MU site, with a focus  on women&#8217;s issues. It&#8217;s structured more like a social network than a blog. There&#8217;s <a href="http://www.blazenewmedia.com/articles/chickspeak-a-wordpress-mu-based-social-network">an article outlining ChickSpeak&#8217;s development</a> that&#8217;s interesting, as well. <a class='via' href="http://photomatt.net/">via: photomatt</a></li>
<li>If you grew up in the eighties like my wife and I, then you can remember when musician <a href="http://blog.thomasdolby.com/">Thomas Dolby</a> was blinding everybody with science.</li>
<li><a href="http://politicalticker.blogs.cnn.com/">CNN&#8217;s Political Ticker</a> blog is a WordPress.com <a href="http://wordpress.com/vip-hosting/">VIP Hosting</a> site.</li>
<li>Robert Scoble&#8217;s <a href="http://scobleizer.com/">Scobleizer</a> blog is another WordPress.com VIP site. Scoble has been an icon in weblog circles for many years now, and is famous for his prolific output, as well as for being an author and a former Microsoft technical evangelist .</li>
<li><a href="http://yodel.yahoo.com/">Yodel Anecdotal</a> is Yahoo&#8217;s corporate blog.
</li>
<li><a href="http://www.deliciousdays.com/">delicious:days</a> is a food blog that looks good enough to eat. Simply beautiful.</li>
<li><a href="http://center.arc.nasa.gov/">NASA Ames Research Center</a> is powered by WordPress. This group is responsible for many of NASA&#8217;s cutting-edge research projects.</li>
<li><a href="http://blog.us.playstation.com/">PlayStation.Blog</a> is the official PlayStation blog from Sony U.S.</li>
<li>Nancy Pelosi, the first female Speaker of the House, has a blog called <a href="http://speaker.gov/blog/">The Gavel</a>. WordPress is in ur guvrnment blogging ur lejislashun!</li>
<li>Ford Motor Company&#8217;s <a href="http://autoshows.ford.com/">Global Auto Shows</a> site doesn&#8217;t look much like a blog, but it&#8217;s all wrapped up in WordPressian goodness.</li>
<li><a href="http://www.cssremix.com/"><acronym title='Cascading Style Sheets'><span class='caps'>CSS</span></acronym> Remix</a> is a showcase of sites with<br />
great design. And the site itself looks schweet.</li>
<li><a href="http://www.welovewp.com/">welovewp.com</a> highlights many WP-powered sites. Some are business-oriented, some are more standard blogs, but all of them have really great design. Oh, and of course, welovewp.com is powered  by WordPress, as well.</li>
</ul>
<p>
Of course, the sites I&#8217;ve listed here are only the tip of the iceburg. There are <em>tons</em> of fantastic WordPress sites in the wild that deserve as much attention as these. Do you know of some? Post them here, and whenever somebody asks you about great WordPress sites, you can just give them a link to this post!
</p>
<div style="text-align:center;width:468px;margin:0 auto;"><a href="http://www.woothemes.com/amember/go.php?r=26427&#038;i=b43"><img src="http://dougal.gunters.org/wordpress/wp-content/uploads/2007/07/468x60b.jpg" border=0 alt="WooThemes - Quality Themes, Great Support" width=468 height=60></a></div>


<p>Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2003/09/09/powered-by-wordpress' rel='bookmark' title='Permanent Link: Powered by WordPress'>Powered by WordPress</a></li>
<li><a href='http://dougal.gunters.org/blog/2009/01/14/awesome-spam-filtering-for-wordpress' rel='bookmark' title='Permanent Link: Awesome spam filtering for WordPress'>Awesome spam filtering for WordPress</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/09/22/css-powered-slashdot-goes-live' rel='bookmark' title='Permanent Link: CSS-powered Slashdot goes live'>CSS-powered Slashdot goes live</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://dougal.gunters.org/blog/2007/07/16/14-awesome-wordpress-powered-sites/feed</wfw:commentRss>
		<slash:comments>141</slash:comments>
		</item>
		<item>
		<title>Perl geekery: building hashes</title>
		<link>http://dougal.gunters.org/blog/2007/06/21/perl-geekery-building-hashes?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
		<comments>http://dougal.gunters.org/blog/2007/06/21/perl-geekery-building-hashes#comments</comments>
		<pubDate>Thu, 21 Jun 2007 10:31:58 +0000</pubDate>
		<dc:creator>Dougal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://dougal.gunters.org/blog/2007/06/21/perl-geekery-building-hashes</guid>
		<description><![CDATA[<p>
Say we&#8217;re writing a program in Perl, and we need to pass a lot of data back and forth between subroutines. Using global variables is bad practice, and we often use the slightly-less-bad method of passing around a big hash variable. But it&#8217;s a pain to always use the values in the hash, so a lot of our code uses individual scalar variables, and stick them into (and pull them out of) the hash as needed. But when you have a <em>lot</em> of values to move around, it&#8217;s a pain in the neck. You don&#8217;t want a big, ugly block of code like this:
</p>
<pre><code>
#...assume that we declared %hash,
#   $foo, $bar, $baz, etc previously...
$hash{'foo'} = $foo;
$hash{'bar'} = $bar;
$hash{'baz'} = $baz;
# ...ad nauseum...
</code></pre>
<p>
Surely, there&#8217;s a more elegant way to do this, right? Of course there is. [...]</p>


Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2004/07/12/a-php-question' rel='bookmark' title='Permanent Link: A PHP Question'>A PHP Question</a></li>
<li><a href='http://dougal.gunters.org/blog/2002/04/23/bees-beavers-and-other-busy-people' rel='bookmark' title='Permanent Link: Bees, Beavers, and Other Busy People'>Bees, Beavers, and Other Busy People</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/02/01/server-update' rel='bookmark' title='Permanent Link: Server update'>Server update</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>
Say we&#8217;re writing a program in Perl, and we need to pass a lot of data back and forth between subroutines. Using global variables is bad practice, and we often use the slightly-less-bad method of passing around a big hash variable. But it&#8217;s a pain to always use the values in the hash, so a lot of our code uses individual scalar variables, and stick them into (and pull them out of) the hash as needed. But when you have a <em>lot</em> of values to move around, it&#8217;s a pain in the neck. You don&#8217;t want a big, ugly block of code like this:
</p>
<pre><code>
#...assume that we declared %hash,
#   $foo, $bar, $baz, etc previously...
$hash{'foo'} = $foo;
$hash{'bar'} = $bar;
$hash{'baz'} = $baz;
# ...ad nauseum...
</code></pre>
<p>
Surely, there&#8217;s a more elegant way to do this, right? Of course there is. The mantra of perl programmers is <acronym title='There is More Than One Way To Do It (tim toady)'><span class='caps'>TMTOWTDI</span></acronym> (There&#8217;s More Than One Way To Do It)! The first and most obvious approach that comes to mind is to use &#8220;variable variables&#8221;, technically known as &#8220;symbolic references&#8221;:
</p>
<pre><code>
my %hash;
my @vars = qw(foo bar baz);
foreach my $var (@vars) {
  # This uses a symbolic reference. When $var is 'foo',
  # then saying $$var is like saying $foo.
  $hash{$var} = $$var;
}
</code></pre>
<p>
The problem is that symbolic references are frowned upon, and will cause perl to get angry with you if you&#8217;re running with <code>use strict</code> (as you should be). You can get around this by declaring the scope of <var>$foo</var> and friends as &#8216;our&#8217; instead of &#8216;my&#8217;, and by using <code>no strict 'refs'</code> inside the <code>foreach</code> loop. I&#8217;m pretty sure that this wouldn&#8217;t cause any memory leaks, but it&#8217;s still an iffy solution because you have to change the scope of a bunch of your variables to &#8216;our&#8217;, which might have undesired side-effects.
</p>
<p>
The next refactoring is a nice improvement. The main difference is that it requires you to stick your list of values into a temporary array. Just keep in mind that this array will be modified (emptied) in the process:
</p>
<pre><code>
my %hash;
my @keys = qw(foo bar baz);
my @values = ($foo, $bar, $baz);
foreach my $key (@keys) {
  $hash{$key} = shift @values;
}
</code></pre>
<p>
Ah, much better! No problems running strict, and not too ugly. A final improvement, suggested to me by David Narayan, is to use a hash slice:
</p>
<pre><code>
my %hash;
my @keys = qw(foo bar baz);
my @values = ($foo, $bar, $baz);
@hash{@keys} = @values;
</code></pre>
<p>
That&#8217;s about as succinct as it&#8217;s going to get. The only disadvantage here might be if your list of key/value pairs was large, this would probably use a lot of memory. In that case, you&#8217;d probably want to use the <code>foreach</code> loop, as in the previous example.</p>


<p>Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2004/07/12/a-php-question' rel='bookmark' title='Permanent Link: A PHP Question'>A PHP Question</a></li>
<li><a href='http://dougal.gunters.org/blog/2002/04/23/bees-beavers-and-other-busy-people' rel='bookmark' title='Permanent Link: Bees, Beavers, and Other Busy People'>Bees, Beavers, and Other Busy People</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/02/01/server-update' rel='bookmark' title='Permanent Link: Server update'>Server update</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://dougal.gunters.org/blog/2007/06/21/perl-geekery-building-hashes/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using the WordPress Object Cache</title>
		<link>http://dougal.gunters.org/blog/2006/07/21/using-the-wordpress-object-cache?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
		<comments>http://dougal.gunters.org/blog/2006/07/21/using-the-wordpress-object-cache#comments</comments>
		<pubDate>Fri, 21 Jul 2006 16:46:57 +0000</pubDate>
		<dc:creator>Dougal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://dougal.gunters.org/blog/2006/07/21/using-the-wordpress-object-cache</guid>
		<description><![CDATA[<p>
I&#8217;ve been planning to write up a plugin to serve as an example of using the <a href="http://codex.wordpress.org/Function_Reference/WP_Cache">WordPress Object Cache</a>, but haven&#8217;t had time to finish it up. However, this topic came up on the <a href="http://codex.wordpress.org/Mailing_Lists#Hackers">wp-hackers mailing list</a> recently, so I thought that I would go ahead and give a brief rundown on how to use the cache from within your own plugins.
</p>
<p>
The goal of the WordPress Object Cache is to provide a way to persistently store results from expensive queries in an external cache file. [...]</p>


Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2008/08/29/xcache-object-cache-plugin-for-wordpress-25' rel='bookmark' title='Permanent Link: XCache Object Cache Plugin for WordPress 2.5+'>XCache Object Cache Plugin for WordPress 2.5+</a></li>
<li><a href='http://dougal.gunters.org/blog/2007/06/19/wp-cache-fix-for-content-type-in-feeds' rel='bookmark' title='Permanent Link: WP-Cache fix for Content-Type in feeds'>WP-Cache fix for Content-Type in feeds</a></li>
<li><a href='http://dougal.gunters.org/blog/2009/08/26/w3-total-cache-plugin' rel='bookmark' title='Permanent Link: W3 Total Cache Plugin'>W3 Total Cache Plugin</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;ve been planning to write up a plugin to serve as an example of using the <a href="http://codex.wordpress.org/Function_Reference/WP_Cache">WordPress Object Cache</a>, but haven&#8217;t had time to finish it up. However, this topic came up on the <a href="http://codex.wordpress.org/Mailing_Lists#Hackers">wp-hackers mailing list</a> recently, so I thought that I would go ahead and give a brief rundown on how to use the cache from within your own plugins.
</p>
<p>
The goal of the WordPress Object Cache is to provide a way to persistently store results from expensive queries in an external cache file. This lets us avoid re-querying the database or re-fetching information from an external web service if we think that the data hasn&#8217;t changed. It should be noted, however, that some server environments have trouble using the cache. It is up to you to monitor your server to determine whether use of the cache will benefit your sites,</p>
<p>
Using the object cache is actually quite simple. You write data to the cache using <code>wp_cache_set()</code>, and you read cached data with <code>wp_cache_get()</code>.
</p>
<p>
Before I get to the sample code, there are some other things you&#8217;ll need to check. The object cache is disabled by default. In order to enable it, you&#8217;ll need to edit your <code>wp-config.php</code> file. Add the following lines, after the setting for <code>WP_LANG</code>:
</p>
<pre><code>
// Enable the WordPress Object Cache:
define(ENABLE_CACHE, true);
</code></pre>
<p>
Also, make sure that there is <strong>not</strong> a define for a <code>DISABLE_CACHE</code>  constant. In addition, you will need to make sure that you have a <code>wp-content/cache</code> subdirectory on your host, and that it is writable by your web server process. I assume that if you are planning to write code to use the object cache, that you know how to handle this on your host server.
</p>
<p>
That said, let&#8217;s take a look at how you use the <code>wp_cache_get()</code> and wp_cache_set()</code> functions in your own code. First, we'll examine how we put data into the cache. Think of the cache as a set of containers, each of which can store several data packets. You can name the containers and the packets within, so that you know how to retrieve them later. In these examples, I am naming the container <var>mycache</var>, and we'll call the data packet <var>mysettings</var>. It would probably be a good convention to name your own container based on the name of your plugin, and name the packets based on what kind of information you are storing (e.g. <var>userdata</var> or <var>popularpostinfo</var>).
</p>
<p>
Here's how we write data to the cache:
</p>
<pre><code>
  // Whenever we need to rewrite the cache data:
  // This could be calling a database, webservice, etc.
  $mydata = my_complicated_data_query();
  $myexpire = 60 * 60 * 24; // Cache data for one day (86400 seconds)
  wp_cache_set('mysettings', $mydata, 'mycache', $myexpire);
</code></pre>
<p>
You'll have to determine the best point in your code to do this depending on what kind of data you're caching. For example, if you are caching user profile data, you might want to update the cache anytime a user's profile changes by hooking into the <code>profile_update()</code> <acronym title='Application Interface'><span class='caps'>API</span></acronym> hook.
</p>
<p>
Now, when you want to avoid that complicated database query, check the cache first. If your information is not already in the cache, or if it has expired, <code>wp_cache_get()</code> will return <var>false</var>. In that case, you'll need to re-query the database for the information. Otherwise, it will return whatever data structure that you previously stored.
</p>
<pre><code>
  // First of all, before you try to access the user data, check
  // the cache.
  $mydata = wp_cache_get('mysettings', 'mycache');

  if (false === $mydata) {
    // The cache data doesn't exist or it's expired.
    // Do whatever we need to populate $mydata from the
    // database normally... 

    $mydata = my_complicated_data_query();

    // Since we know that the cache isn't up to date, we should
    // write this fresh information to it now, so that we can avoid
    // the query next time.
    $myexpire = 60 * 60 * 24; // Cache data for one day (86400 seconds)
    wp_cache_set('mysettings', $mydata, 'mycache', $myexpire);
  }
</code></pre>
<p>
It's up to you to decide an appropriate amount of time to cache your data and to determine which <acronym title='Application Interface'><span class='caps'>API</span></acronym> action hooks should trigger cache updates. A whole day will be too long for some types of information. But with this basic information in hand, it should be relatively easy for plugin authors to take advantage of the object cache.</p>


<p>Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2008/08/29/xcache-object-cache-plugin-for-wordpress-25' rel='bookmark' title='Permanent Link: XCache Object Cache Plugin for WordPress 2.5+'>XCache Object Cache Plugin for WordPress 2.5+</a></li>
<li><a href='http://dougal.gunters.org/blog/2007/06/19/wp-cache-fix-for-content-type-in-feeds' rel='bookmark' title='Permanent Link: WP-Cache fix for Content-Type in feeds'>WP-Cache fix for Content-Type in feeds</a></li>
<li><a href='http://dougal.gunters.org/blog/2009/08/26/w3-total-cache-plugin' rel='bookmark' title='Permanent Link: W3 Total Cache Plugin'>W3 Total Cache Plugin</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://dougal.gunters.org/blog/2006/07/21/using-the-wordpress-object-cache/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>A Software Development Analogy</title>
		<link>http://dougal.gunters.org/blog/2006/05/23/a-software-development-analogy?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
		<comments>http://dougal.gunters.org/blog/2006/05/23/a-software-development-analogy#comments</comments>
		<pubDate>Tue, 23 May 2006 18:20:03 +0000</pubDate>
		<dc:creator>Dougal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://dougal.gunters.org/blog/2006/05/23/a-software-development-analogy</guid>
		<description><![CDATA[<p>
Alice takes her car to a repair shop on Monday. She walks inside and talks to Bob, the customer service representative behind the counter. &#8220;My car seems to work pretty well, but occassionally it makes an odd noise. When can you have it fixed, and how much will it cost?&#8221;
</p>
<p>
Bob smiles and replies, &#8220;we can have your car ready by noon on Friday, and it will cost $200.&#8221; Alice says that this is acceptable, and leaves her car to be worked on.
</p>
<p>
On Wednesday afternoon, Bob talks to Charlie, the mechanic. &#8220;How are you progressing on Miss Alice&#8217;s repairs?&#8221; Charlie gives Bob a blank look.
</p>
<p>
&#8220;I gave it a quick look yesterday, but I haven&#8217;t even started working on her car. [...]</p>


Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2002/11/12/software-development' rel='bookmark' title='Permanent Link: Software Development'>Software Development</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/09/30/software-taxes' rel='bookmark' title='Permanent Link: Software taxes'>Software taxes</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/05/24/calendar-software-recommendation' rel='bookmark' title='Permanent Link: Calendar Software Recommendation?'>Calendar Software Recommendation?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>
Alice takes her car to a repair shop on Monday. She walks inside and talks to Bob, the customer service representative behind the counter. &#8220;My car seems to work pretty well, but occassionally it makes an odd noise. When can you have it fixed, and how much will it cost?&#8221;
</p>
<p>
Bob smiles and replies, &#8220;we can have your car ready by noon on Friday, and it will cost $200.&#8221; Alice says that this is acceptable, and leaves her car to be worked on.
</p>
<p>
On Wednesday afternoon, Bob talks to Charlie, the mechanic. &#8220;How are you progressing on Miss Alice&#8217;s repairs?&#8221; Charlie gives Bob a blank look.
</p>
<p>
&#8220;I gave it a quick look yesterday, but I haven&#8217;t even started working on her car. I&#8217;m still finishing up the work on Mr. Durham&#8217;s truck.&#8221;
</p>
<p>
&#8220;Haven&#8217;t started? We have to get her car working by Friday at noon!&#8221; Bob exclaims.
</p>
<p>
Charlie narrows his eyes and shrugs. &#8220;That&#8217;s not going to happen. I had to order some parts, and they won&#8217;t even be here until tomorrow.&#8221;
</p>
<p>
Bob gives Charlie a pained look and sputters, &#8220;surely you realize that Miss Alice is an important customer? She works for a company that has a fleet of leased cars, and they get all their servicing from us. If we don&#8217;t have her car ready on time, we could lose that contract!&#8221;
</p>
<p>
Charlie looks back and Bob and replies, &#8220;Maybe you should have thought of that earlier. And maybe you should have asked me what my repair schedule looked like before you gave her an ETA on her repairs. Better yet, you probably should have asked Dave, since he&#8217;s the shop manager. But, no &#8212; you ignored our normal workflow, and now I&#8217;m going to have to work overtime because of your mistake. And when this lady gets her car back, if everything works fine, she&#8217;ll send you a nice thank you note, and the shop owner will congratulate you. But if I make a mistake in my hurry to meet your unreasonable deadline, you&#8217;ll blame me, and the shop owner might fire me. Is that basically right?&#8221;
</p>
<p>
&#8220;Yup.&#8221;
</p>
<p>
&#8220;I guess I&#8217;d better get to work, then.&#8221;</p>


<p>Related posts:<ol><li><a href='http://dougal.gunters.org/blog/2002/11/12/software-development' rel='bookmark' title='Permanent Link: Software Development'>Software Development</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/09/30/software-taxes' rel='bookmark' title='Permanent Link: Software taxes'>Software taxes</a></li>
<li><a href='http://dougal.gunters.org/blog/2005/05/24/calendar-software-recommendation' rel='bookmark' title='Permanent Link: Calendar Software Recommendation?'>Calendar Software Recommendation?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://dougal.gunters.org/blog/2006/05/23/a-software-development-analogy/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

<!-- Served from: dougal.gunters.org @ 2010-08-01 00:13:19 by W3 Total Cache -->