<?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>puremango.co.uk &#187; PHP</title>
	<atom:link href="http://www.puremango.co.uk/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.puremango.co.uk</link>
	<description>innovative coding, tutorials, web stuff. celebrating 5 years online.</description>
	<lastBuildDate>Thu, 02 Sep 2010 09:04:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Fast PHP array_unique for removing duplicates</title>
		<link>http://www.puremango.co.uk/2010/06/fast-php-array_unique-for-removing-duplicates/</link>
		<comments>http://www.puremango.co.uk/2010/06/fast-php-array_unique-for-removing-duplicates/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 08:23:21 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array_flip]]></category>
		<category><![CDATA[array_reverse]]></category>
		<category><![CDATA[array_unique]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=1039</guid>
		<description><![CDATA[PHP&#8217;s native dedupe function, array_unique, can be slow for large amount of input. Here I&#8217;m going to talk about a simple function that performs the same task but which runs a lot faster. Often, people spout PHP optimisation advice that is incredibly misguided, so I want to make it clear up-front that you should be [...]]]></description>
			<content:encoded><![CDATA[<p>PHP&#8217;s native dedupe function, <a href="http://php.net/manual/en/function.array-unique.php" target="_blank">array_unique</a>, can be slow for large amount of input. Here I&#8217;m going to talk about a simple function that performs the same task but which runs a lot faster.</p>
<p>Often, people spout PHP optimisation advice that is incredibly misguided, so I want to make it clear up-front that you should be benchmarking your scripts using xdebug before you start optimising, and very often the real bottlenecks cannot be avoided by using &#8220;micro-optimization&#8221;. Here&#8217;s a nice PDF on <a href="http://ilia.ws/files/Dutch_PHP_Conference_2010_OPM.pdf" target="_blank">Common Optimization Mistakes</a>.</p>
<p>Now I&#8217;ve got that disclaimer out of the way, I believe it&#8217;s OK to talk about making a faster array_unique because it&#8217;s often used on large amounts of data &#8211; for example removing duplicate email addresses, and as such there are genuine use cases for a fast array_unique in PHP. Also our fast_unique function can be several seconds faster than array_unique so we&#8217;re not necessarily talking about micro-optimisation here; on 200k duplicate entries, array_unique takes nearly 5 seconds on my windows dev box, fast_unique takes &lt;1 second on the same data. On 2 million entires the results are staggering &#8211; performance graphs are given below (but then, why are you doing that kind of work in PHP?).</p>
<p>The function looks like this:<br />
<span id="more-1039"></span></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> fast_unique<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Code documented at: http://www.puremango.co.uk/?p=1039</span>
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">array_flip</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_flip</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_reverse</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This will return a copy of the input array with duplicates removed and keys preserved.</p>
<p>When using this function, there are some important caveats you should be aware of:</p>
<ol>
<li>The data is not returned in the same order as array_unique would return it. You can add a ksort afterwards, but this will reduce the speed savings. Key order preservation is often not required, so I haven&#8217;t included that by default. Key association is preserved, just not the ordering.</li>
<li>This only works with strings or integers for keys and values. You could hack together a __toString walk to get it to deal with objects too, and I may do that at some point.</li>
<li>I haven&#8217;t yet benchmarked memory consumption; memory_get_peak_usage doesn&#8217;t seem to work properly with the native array_unique. Help?</li>
<li>For smaller amounts of data (&lt;50k entries) I would suggest keeping array_unique for code-clarity. fast_unique is still faster than array_unique, but at those levels, you&#8217;re talking less than 0.5 seconds difference.</li>
</ol>
<p>To explain how it works, let&#8217;s go through an example: let&#8217;s say we start with this array:</p>
<p><code>0=&gt;apple<br />
1=&gt;biscuit<br />
2=&gt;cabbage<br />
3=&gt;biscuit<br />
</code><br />
When we array_flip it, we try to create an array like this:</p>
<p><code>apple=&gt;0<br />
biscuit=&gt;1<br />
cabbage=&gt;2<br />
biscuit=&gt;3<br />
</code><br />
but now that &#8220;biscuit&#8221; is a key it can&#8217;t have two values, so the &#8220;biscuit=&gt;3&#8243; assignment overwrites the first biscuit value, and we end up with this:</p>
<p><code>apple=&gt;0<br />
biscuit=&gt;3<br />
cabbage=&gt;2<br />
</code><br />
then we flip it again to get key=&gt;value pairs again instead of value=&gt;keys:</p>
<p><code>0=&gt;apple<br />
3=&gt;biscuit<br />
2=&gt;cabbage<br />
</code><br />
And there we go &#8211; duplicates removed! Now in this example, later keys (i.e. 3=&gt;biscuit) overwrote earlier ones (1=&gt;biscuit) &#8211; but with PHP&#8217;s native array_unique earlier keys are preserved, so in the fast_unique function above, we reverse the array before flipping to mimic that functionality &#8211; if you don&#8217;t care about keys then go ahead and strip it out.</p>
<p>I&#8217;ve benchmarked this code for speed against various input sizes: 2k,20k,200k,2m, and various levels of uniqueness: 0%, 50% and 100%. An &#8220;input size&#8221; of 2000 means we fed in an array with 2000 entries whose values are strings between 1 and 200 characters in length. 2 million duplicate entries took too long to generate, so I didn&#8217;t  benchmark that size for the 0% unique test.</p>
<p style="text-align: center;"><img class="aligncenter" title="0% unique data" src="http://www.puremango.co.uk/benchmarks/0pc.png" alt="" width="330" height="273" /></p>
<p style="text-align: center;"><img class="aligncenter" title="50% unique data" src="http://www.puremango.co.uk/benchmarks/50pc.png" alt="" /></p>
<p style="text-align: center;"><img class="aligncenter" title="100% unique data" src="http://www.puremango.co.uk/benchmarks/100pc.png" alt="" /></p>
<p>So there you have it; quite dramatic for large amounts of data. I feel I should mention that the &#8220;double flip&#8221; method is nothing new; there are notes on the PHP docs to the effect that &#8220;the array flip method is faster&#8221;, but I thought a rigorous benchmarking and documentation was worth doing, so please don&#8217;t hate me if you &#8220;invented&#8221; this years ago ;)</p>
<p>Also, if this is the first time you&#8217;ve read about PHP optimisation, do remember that most of the time it&#8217;s pointless trying to speed up PHP code. Array_unique is a special case because it&#8217;s often used on large arrays (and if your array is smaller than around 50k entries, it&#8217;s probably not worth using this function). Read that <a href="http://ilia.ws/files/Dutch_PHP_Conference_2010_OPM.pdf" target="_blank">Common Optimization Mistakes PDF</a>, and my other post on <a href="http://www.puremango.co.uk/2010/04/fast-php/" target="_self">fast PHP</a> for tips on how to correctly approach PHP optimisation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/06/fast-php-array_unique-for-removing-duplicates/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Fast PHP &#8211; effective optimisation and bottleneck detection</title>
		<link>http://www.puremango.co.uk/2010/04/fast-php/</link>
		<comments>http://www.puremango.co.uk/2010/04/fast-php/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 14:42:14 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=867</guid>
		<description><![CDATA[PHP is not the fastest language on earth. That honour probably goes to machine code. But like many high-level languages, PHP provides some handy abstractions, like named variables, hashmaps (associative arrays), a C-like syntax, object oriented capabilities, loose typing and so on &#8211; we trade processing speed for development ease. So it&#8217;s quite a common [...]]]></description>
			<content:encoded><![CDATA[<p>PHP is not the fastest language on earth. That honour probably goes to machine code. But like many high-level languages, PHP provides some handy abstractions, like named variables, hashmaps (associative arrays), a C-like syntax, object oriented capabilities, loose typing and so on &#8211; we trade processing speed for development ease.</p>
<p>So it&#8217;s quite a common problem that people find their large PHP web applications running quite slowly.</p>
<p>Here are some frequently encountered bottlenecks found in web applications generally, and PHP specifically:</p>
<p><span id="more-867"></span><strong>1) The Database</strong></p>
<p>So often we treat databases like big persistent arrays. They&#8217;re not.</p>
<p>First of all, remember that anything that goes in or comes out of the DB is going to have to be transferred to your web server. That&#8217;s a network hit. So storing images or other binary data in the database is generally a Bad Idea (for <a href="http://stackoverflow.com/questions/527801/php-to-store-images-in-mysql-or-not" target="_blank">other reasons too</a>). But it&#8217;s not just images &#8211; all database traffic will happen over the local network, so if you&#8217;ve got big chunks of HTML or thousands of rows of data flicking back and forth you need to be aware that that will entail a network hit. mySQL compression can help with this, but be sure to benchmark for your own scripts &#8211; it may be that the CPU overhead cancels out the benefit of mySQL compression for your servers.</p>
<p>Secondly, a great many databases are thrown together without much thought for optimisation. You need to look closely at what queries you&#8217;ll be running, and optimise the structure of the database for them. Often it&#8217;s as simple as adding an index, but sometimes you might need to examine your queries to make sure they&#8217;re doing what they should be.</p>
<p>The database is a very very common source of speed problems &#8211; you will often find that simply adding an index to a table will solve your troubles. Look to the database first!</p>
<p>Here&#8217;s a very neat tip from google&#8217;s <a href="http://code.google.com/speed/articles/optimizing-php.html">php optimisation</a> page:</p>
<blockquote><p><strong>Avoid doing SQL queries within a loop</strong></p></blockquote>
<p>They note that it&#8217;s faster to run one query like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #66cc66;">&#40;</span>first_name<span style="color: #66cc66;">,</span>last_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Doe&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Jane&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Doe&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Than it is to run two queries like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #66cc66;">&#40;</span>first_name<span style="color: #66cc66;">,</span>last_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Doe&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #66cc66;">&#40;</span>first_name<span style="color: #66cc66;">,</span>last_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Jane&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Doe&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>A great little SQL optimisation tip. Construct one query in a loop and run it once outside the loop rather than running the query inside the loop.</p>
<p><strong>2) Client-side optimisation.<br />
</strong></p>
<p>Often when we hear about &#8220;slow web applications&#8221;, people are actually talking about page load time, which can often be quite independent of the server-side code optimisation side of things. Take a good look at your images &#8211; are they uncompressed PNGs? Do you really lose anything by converting them over to 90% quality JPGs instead? You&#8217;ll certainly gain page load speed and reduce bandwidth. Also make sure you&#8217;re using gzip compression on the web server where applicable, and think about minifying your css, javascript and html code. Often user complaints about sluggish code is actually more related to the delivery rather than the processing. In certain use cases (eg toolbar icons), using CSS sprites is a good client-side optimisation, but don&#8217;t forget about the hit on initial devlopment time.</p>
<p>Install the firebug addons <a href="http://code.google.com/speed/page-speed/" target="_blank">pagespeed</a> and <a href="http://developer.yahoo.com/yslow/" target="_blank">YSlow</a> to get a good look at where the client-side bottlenecks are.</p>
<p><strong>3) Slow Code</strong></p>
<p>PHP is easy. Easy to get wrong that is. There are a lot of posts out there with micro-optimisation techniques, which can work wonders in very specific circumstances, but generally speaking these &#8220;tips&#8221; will be counter-productive in the long run, forcing you to code un-naturally and making your code resistant to changes. For example, using <a href="http://www.phpbench.com/" target="_blank">&amp; to access 1d arrays is faster</a>, but what if you add a dimension later on in development &#8211; will you remember that it hurts performance on &gt;1d arrays? And what if the next version of PHP changes that behaviour?</p>
<p>However, there are a few optimisations that are so blindingly obvious, yet often ignored &#8211; caching the count() in a loop for instance:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arr</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>versus</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #339933;">=</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arr</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #000088;">$c</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In the first snippet, that count function runs on every iteration. In the second, it runs only once. This really can have a big impact not only on a per-script basis, but also on the server as a whole.</p>
<p>You should really work to make the second style a habit. It&#8217;s hardly any different syntactically but it offers a huge potential performance increase.</p>
<p>But aside from a few simple good practice optimisations like that one, how do you tell where the bottlenecks in your PHP code really are?</p>
<p>A lot of people just throw down echo microtime(); in a bunch of likely-looking places and run it a few times. Let me share a tip about <strong>code profiling</strong>.</p>
<p>Using the <a href="http://xdebug.org/" target="_blank">xdebug extension</a>, we can get an insight into the  speed footprint of every single line of function call in a script. Here&#8217;s an example of the output we can get:</p>
<p><img class="aligncenter" title="winCacheGrind xdebug output" src="http://www.puremango.co.uk/xdebug/xdebug.png" alt="" width="635" height="475" /></p>
<p>We have a nice breakdown of the amount of time (percentage or ms) that each function call takes, how many times it is run, and whether the time is taken up within that function (self) or elsewhere (cumulative). And you can get this breakdown simply by appending ?XDEBUG_PROFILE to the GET request &#8211; no code changes required!</p>
<p>Sadly, there is one caveat: it&#8217;s not very stable on windows. I would moan at you and tell you that you should be developing on the same architecture as your live servers, but as you can clearly see from the screenshot, I&#8217;m still humping Bill Gates too.</p>
<p>Here&#8217;s a little post about <a href="http://elrems.wordpress.com/2008/02/12/profiling-php-with-xdebug-and-wincachegrind/" target="_blank">setting up xdebug and wincachegrind for PHP code profiling</a>. It&#8217;s pretty easy to do.</p>
<p><strong>4) Repeated work is inefficient</strong></p>
<p>So many content managed web applications feature code like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span> <span style="color: #0000ff;">&quot;db.php&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">&quot;header.php&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT Content FROM Pages WHERE PageID=5&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #339933;">,</span>CN<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Content'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;error fetching content&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">&quot;footer.php&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And I mean, that&#8217;s one of the nice things about PHP &#8211; you can quickly slap together an interface between the DB and HTML &#8211; wonderful for rapid prototyping.</p>
<p>But think about it &#8211; how often does that page content change? Wouldn&#8217;t it be better to link to page.html, and when the administrator hits save in the backend CMS, overwrite page.html with the generated content?</p>
<p>That way the million users who request that page every month don&#8217;t even spawn a PHP process &#8211; apache can handle that entire transaction. This means the page is served super-quick instead of running the same code with the same input and the same output a million times. Everyone benefits &#8211; the server is running less duplicate code, and users get faster web applications.</p>
<p>It&#8217;s not just rarely-accessed parts of the site that can be optimised in this way either.</p>
<p>Consider an online store. Well, why <em>not</em> generate a pretty much static copy of the site &#8211; it only needs to be updated when product info changes. Obviously you&#8217;ll want to look at your own application to see where it makes sense to cache on the disk instead of generating on-the-fly, but it&#8217;s an option that&#8217;s too often overlooked.</p>
<p>That brings us nicely on to:</p>
<p><strong>5) Caching</strong></p>
<p>This is where the line between web developer and server admin starts to blur, but for large scale applications you will need to start thinking about opcode caching, memcache, squid, mySQL query-cache and other types of cache.</p>
<p>These types of solution are almost always highly tailored to the individual needs of the application, so I will not talk much about it &#8211; the chances are that if you need this level of caching, you already know more about it than I do, so I won&#8217;t pretend to be an expert in this area. Here are some links/pics from the guys who really do know about this kind of stuff:</p>
<ul>
<li><a href="http://blog.reddit.com/2010/03/and-fun-weekend-was-had-by-all.html" target="_blank">Reddit&#8217;s architecture</a></li>
<li><a href="http://www.krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications/" target="_blank">Digg&#8217;s architecture</a></li>
<li><a href="http://upload.wikimedia.org/wikipedia/commons/4/4f/Wikimedia-servers-2009-04-05.svg" target="_blank">Wikipedia&#8217;s architecture</a></li>
<li><a href="http://talks.php.net/show/acc_php/1" target="_blank">Some slides on accelerating PHP</a></li>
</ul>
<p>That&#8217;s all for today. To recap:</p>
<ol>
<li>Don&#8217;t transfer more than you need to across the network.</li>
<li>Make sure your tables are indexed properly.</li>
<li>Don&#8217;t write slow code.</li>
<li>Cache rarely-changing output in files on disk.</li>
<li>Draw out your architecture to identify where more serious caching can happen.</li>
</ol>
<p>Thanks to <a href="http://www.toosweettobesour.com/" target="_blank">Daniel at toosweettobesour</a> for taking me to task about the micro-optimisations ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/04/fast-php/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Super Useful Web Dev Tools</title>
		<link>http://www.puremango.co.uk/2010/03/super-useful-web-dev-tools/</link>
		<comments>http://www.puremango.co.uk/2010/03/super-useful-web-dev-tools/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 13:25:47 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[msie]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=850</guid>
		<description><![CDATA[OMG, it&#8217;s been a whole month since my last update. I have draft posts about all kinds of Good Stuff™, but none are quite publishable yet. So today I&#8217;m just going to point you at a few great resources I use all the time while doing my web development magic: Before I start on the [...]]]></description>
			<content:encoded><![CDATA[<p>OMG, it&#8217;s been a whole month since my last update.</p>
<p>I have draft posts about all kinds of Good Stuff™, but none are quite publishable yet. So today I&#8217;m just going to point you at a few great resources I use all the time while doing my web development magic:</p>
<p><span id="more-850"></span></p>
<p>Before I start on the list proper, I&#8217;m going to assume you already know and love <a href="http://getfirebug.com/" target="_blank">firebug</a>, if not, go away and don&#8217;t come back till you&#8217;ve got it. I mean really, firebug has moved js development forward no end.</p>
<p><strong>Cool (free) Tools That You Need:</strong></p>
<ul>
<li><a href="http://phpjs.org/" target="_blank"><strong>php.js</strong></a> &#8211; a project to port PHP functions to Javascript. Ever wanted to use number_format() in JS? Or date()? Now you can.</li>
<li><a href="http://www.my-debugbar.com/wiki/IETester/HomePage" target="_blank"><strong>IETester</strong></a> &#8211; a program that bundles Internet Explorer 5.5, 6, 7 and 8 together so you can open each one in a new tab and test your website in multiple versions of MSIE.</li>
<li><a href="http://weitz.de/regex-coach/" target="_blank"><strong>The Regex  Coach</strong></a> &#8211; you type the target string, then type the regex. It  highlights the matches as you edit the regex. This will save you hours.</li>
<li><a href="http://home.snafu.de/tilman/xenulink.html" target="_blank"><strong>Xenu</strong></a> &#8211; a program that recursively checks a URL for broken links. This should really be the final stage before go-live of any project.</li>
<li><a href="http://webyog.com/en/" target="_blank"><strong>SQLYog</strong></a> &#8211; like phpMyAdmin in an application, but faster and more robust. Does need the firewall opening up though. Nagware.</li>
<li><a href="http://www.getpaint.net/" target="_blank"><strong>Paint.NET</strong></a> &#8211; If MS Paint and Photoshop had a baby, paint.net would be it. The image editor of choice for those of us who &#8220;just want something a bit better than paint&#8221;.</li>
</ul>
<p>That&#8217;s my list of essentials. Sorry this isn&#8217;t a &#8220;proper&#8221; blog post. Hopefully one or two of the tools there will help you out. The Regex Coach is truly great. And completely compatible with PHP&#8217;s <a href="http://uk3.php.net/manual/en/ref.pcre.php" target="_blank">preg </a>functions (ereg is now deprecated), and javascript regular expressions engine. Yay.</p>
<p>Any &#8220;OMFG I can&#8217;t believe he missed that&#8221; additions? btw, does anyone have a good color picker &#8211; one that I can easily copy the current colour from? Because most of the time I have to just remember that it&#8217;s #FE38C4 or whatever. Being able to Ctrl-C directly would be nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/03/super-useful-web-dev-tools/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>allRGB Entry &#8211; PHP Image Manipulation</title>
		<link>http://www.puremango.co.uk/2010/02/allrgb-entry-php-image-manipulation/</link>
		<comments>http://www.puremango.co.uk/2010/02/allrgb-entry-php-image-manipulation/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 08:38:44 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[allrgb]]></category>
		<category><![CDATA[colours]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[imagecreate]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[rgb]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=773</guid>
		<description><![CDATA[The objective of allRGB is simple: To create images with one pixel for every rgb-color (16777216 to be exact); not one color missing, and not one color twice. What a cool project! As regular readers will know, I love messing about with image manipulation in PHP, so when I heard about the allRGB project I [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>The objective of <a href="http://allrgb.com/" target="_blank">allRGB</a> is simple: To create images with one pixel for every <abbr>rgb</abbr>-color (16777216 to be exact); not one color missing, and not one color twice.</p></blockquote>
<p>What a cool project! As regular readers will know, I love messing about with <a href="http://www.puremango.co.uk/tag/imagecreate/" target="_self">image manipulation in PHP</a>, so when I heard about the allRGB project I knew I had to make an entry for it. A few false starts and about half an hour later, I proudly submitted my first entry, a 4096&#215;4096 PNG image containing every single possible RGB colour. As one redditor put it, &#8220;It&#8217;s like poetry, just without words.&#8221;</p>
<p><center><a href="http://www.puremango.co.uk/allrgb/one.png" target="_blank"><img title="All possible colours" src="http://www.puremango.co.uk/allrgb/sm_one.jpg" alt="" width="400" height="400" /></center></a></p>
<p style="text-align: center;"><a href="http://www.puremango.co.uk/allrgb/one.png" target="_blank"><em>Click for the high resolution (only 173Kb)</em></a></p>
<p>And now on to the code:<br />
<span id="more-773"></span><br />
The authors of the allRGB project state that;</p>
<blockquote><p>The most obvious example is a series of 16 by 16 squares, each of which consists of a gradient.</p></blockquote>
<p>But to me the most obvious approach was to simply loop over red (0-255), green (0-255) and blue (0-255) adding a pixel for each colour; as the PHP code below illustrates:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?</span>
&nbsp;
<span style="color: #000088;">$w</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4096</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$h</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4096</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$y</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$im</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ImageCreateTrueColor</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #339933;">,</span> <span style="color: #000088;">$h</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$r</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$r</span><span style="color: #339933;">&lt;=</span><span style="color: #cc66cc;">255</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$r</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$g</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$g</span><span style="color: #339933;">&lt;=</span><span style="color: #cc66cc;">255</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$g</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$b</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$b</span><span style="color: #339933;">&lt;=</span><span style="color: #cc66cc;">255</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$b</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$col</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ImageColorAllocate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$im</span><span style="color: #339933;">,</span><span style="color: #000088;">$r</span><span style="color: #339933;">,</span><span style="color: #000088;">$g</span><span style="color: #339933;">,</span><span style="color: #000088;">$b</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">ImageSetPixel</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$im</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #000088;">$col</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #339933;">&lt;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$x</span><span style="color: #339933;">++;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
				<span style="color: #000088;">$y</span><span style="color: #339933;">++;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-type: image/png&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">ImagePng</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$im</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">ImageDestroy</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$im</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>You&#8217;ll need to up max_execution_time and memory_limit, but it&#8217;s not as hungry as you might imagine; under a minute of processing time on my meager home server.</p>
<p>My entry, which I&#8217;ve imaginatively entitled &#8220;Grid One&#8221;, is still undergoing review with the folks at allRGB, but I hope to be listed in their hall of fame shortly (<a href="http://allrgb.com/grid-one">now listed</a>) :0) It&#8217;s similar to the existing &#8220;<a href="http://allrgb.com/suave">suave</a>&#8221; and &#8220;<a href="http://allrgb.com/tvlines">tvlines</a>&#8221; entries.</p>
<p>And for my next trick? I&#8217;m working on a script to convert any arbitrary image into an allRGB entry. But loops with 16 million iterations need to be carefully optimised. It&#8217;s a fun challenge, especially in PHP.</p>
<p><strong>Update</strong>: Many thanks to Alexander for pointing out that my first attempt didn&#8217;t actually contain all the colours (*blush*) &#8211; code and images updated now :D</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/02/allrgb-entry-php-image-manipulation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Textpad PHP manual lookup tool</title>
		<link>http://www.puremango.co.uk/2010/02/textpad-php-manual-lookup-tool/</link>
		<comments>http://www.puremango.co.uk/2010/02/textpad-php-manual-lookup-tool/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 19:11:40 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=743</guid>
		<description><![CDATA[A little tip for those of us using textpad to develop in PHP. How often do you find yourself having to go back to PHP.net to check up on a function &#8211; is it ($needle, $haystack) or ($haystack, $needle)? I can never remember! With this tool I just need to highlight the function in textpad, [...]]]></description>
			<content:encoded><![CDATA[<p>A little tip for those of us using <a href="http://www.textpad.com">textpad</a> to develop in PHP. How often do you find yourself having to go back to PHP.net to check up on a function &#8211; is it ($needle, $haystack) or ($haystack, $needle)? I can never remember! With this tool I just need to highlight the function in textpad, press Ctrl-1 and up pops php.net in a new tab, opened on that function&#8217;s manual entry. Neat huh?</p>
<p>Here&#8217;s how:</p>
<p><span id="more-743"></span><strong>1) Go to Configure-&gt;Preferences-&gt;Tools-&gt;Add-&gt;DOS Command:</strong></p>
<p><img class="aligncenter" title="Textpad Tools Menu" src="http://www.puremango.co.uk/images/textpad_tool1.png" alt="" width="632" height="372" /></p>
<p><strong>2) Then enter the following in the popup dialog:</strong></p>
<h3 style="padding-left: 30px;"><strong>start http://php.net/manual-lookup.php?pattern=$Sel</strong></h3>
<p><strong> </strong></p>
<p><strong>3) Then </strong><strong>in the tool&#8217;s preferences, </strong><strong>untick &#8220;Capture Output&#8221; and tick &#8220;Close DOS window on exit&#8221;:</strong></p>
<p><img class="aligncenter" title="Textpad Tools Options" src="http://www.puremango.co.uk/images/textpad_tool2.png" alt="" width="632" height="372" /></p>
<p>Now any time you want to lookup a function in your code, simply highlight or double-click it and press Ctrl-1 to be taken to that function&#8217;s manual page on PHP.net, in a new tab in your default web browser.</p>
<p>While we&#8217;re on the topic of textpad tweaks, did you know you can jump to the matching brace by pressing Ctrl-M? Very handy for spaghetti code. Share your textpad PHP IDE tips below! And if you haven&#8217;t already, why not take this opportunity to, you know, actually buy textpad after all this time? &lt;grin&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/02/textpad-php-manual-lookup-tool/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GIFexplode &#8211; community powered web development</title>
		<link>http://www.puremango.co.uk/2009/08/gifexplode-community-powered-web-development/</link>
		<comments>http://www.puremango.co.uk/2009/08/gifexplode-community-powered-web-development/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 18:35:00 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=573</guid>
		<description><![CDATA[Let me share with you a very cool story about strangers coming together and building something. I was browsing reddit yesterday, and I saw a thread entitled &#8220;Someone needs to make a Firefox add-on that lets you step through animated gifs frame by frame&#8220;. I thought &#8220;hey that&#8217;s a nice well defined simple idea&#8221; &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Let me share with you a very cool story about strangers coming together and building something.</p>
<p><a href="http://www.gifexplode.com/c" target="_blank"><img class="alignright" title="I am a tiger" src="http://www.puremango.co.uk/gifexplode/619504tiger.gif" alt="" width="100" height="100" /></a>I was browsing reddit yesterday, and I saw a thread entitled &#8220;<a href="http://www.reddit.com/r/programming/comments/96iok/someone_needs_to_make_a_firefox_addon_that_lets/">Someone needs to make a Firefox add-on that lets you step through animated gifs frame by frame</a>&#8220;. I thought &#8220;hey that&#8217;s a nice well defined simple idea&#8221; &#8211; just the kind of thing I love, so I registered a nice-sounding domain name and started looking at how to use PHP to split an animated gif into its component frames &#8211; I figured it couldn&#8217;t be too hard.<span id="more-573"></span></p>
<p><a href="http://www.gifexplode.com/q" target="_blank"><img class="alignleft" title="Ralph" src="http://www.puremango.co.uk/gifexplode/545934ralph_eats_glue_e0.gif" alt="" width="160" height="120" /></a>It wasn&#8217;t. Less than an hour later, <a href="http://www.gifexplode.com/" target="_blank">GIFexplode.com</a> was up and running with some bare-bones functionality based around some freeware code I&#8217;d found. I posted the link to reddit and thought &#8220;well it&#8217;s not quite a firefox extension but it&#8217;s close enough&#8221; (by the way, click any of the gifs on this page to see how GIFexplode processed them).</p>
<p>Within ten hours, other members of the reddit community had produced a working Firefox extension for GIFexplode, two bookmarklets, a logo, a front-end design and a <a href="http://www.reddit.com/r/programming/comments/96n1x/someone_needs_to_make_a_firefox_addon_that_will/" target="_blank">spoof thread</a>&#8230;</p>
<p>not to mention the <strong>700+ animated gif files</strong> that were uploaded in that first day.</p>
<p><a href="http://www.gifexplode.com/e" target="_blank"><img class="alignright" title="Chimp is not impressed" src="http://www.puremango.co.uk/gifexplode/102664chimpanzee.gif" alt="" /></a>Why did everyone pitch in like that? Well I can&#8217;t speak for anyone else, but I started working on it because I thought it would be an interesting challenge.</p>
<p><strong>Fame?</strong> A little &#8211; but while I got a few upvotes on reddit and earned a little respect, that really doesn&#8217;t go too far online. <strong>Fortune?</strong> Unlikely &#8211; even if GIFexplode became as popular as imageshack or tinyurl (which it won&#8217;t), I&#8217;d still have to work out a good enough revenue model to cover the hosting and bandwidth charges. <strong>Over 1.5GB was uploaded</strong> on that first day, and if GIFexplode carried on at that rate I&#8217;m sure I&#8217;d be asked to upgrade to a private server pretty quickly. <a href="http://www.dreamhost.com/r.cgi?492537" target="_blank">Dreamhost </a>coped excellently with the traffic though.</p>
<p><a href="http://www.gifexplode.com/endless.htm" target="_blank"><img class="alignleft" title="Endless. This one isn't actually processed correctly by GIFexplode.. yet." src="http://www.puremango.co.uk/gifexplode/794844one_1.gif" alt="" width="160" height="120" /></a>So that&#8217;s the story of how GIFexplode was born and, as one commenter aptly phrased it, put in front of &#8220;a live firing squad challenge&#8221;!</p>
<p>As to the future? Well there are a few extra features I want to implement, but I really have <a href="http://www.puremango.co.uk/2009/06/adaptive-web-sites/" target="_blank">more important work</a> to be doing this month. I expect the traffic to drop very sharply and hit around 10 visits per day by the end of September. Perhaps I&#8217;ll post another followup in a few months once we have some more features and the code is a bit more robust.</p>
<p>But in the meantime, <strong>a sincere thankyou</strong> to everyone who chipped in &#8211; if I ever do become a millionaire from this I&#8217;ll make sure you get your slice.</p>
<p><a href="http://www.gifexplode.com/d" target="_blank"><img class="alignright" title="Picard" src="http://www.puremango.co.uk/gifexplode/4290711237976746_picard2.gif" alt="" width="150" height="200" /></a><strong>Some random stats:</strong></p>
<ul>
<li>Around one third of the uploaded files were porn. I am amazed it wasn&#8217;t a higher proportion.</li>
<li>The bouncing gif (you know the one I mean) was uploaded at least 200 times &#8211; at one point I was considering making a static page just for that gif (I still may do)</li>
<li>The largest file uploaded was a 5.14Mb file of a <a href="http://commons.wikimedia.org/wiki/File:Cicada_molting_animated-2.gif" target="_blank">cicada molting</a></li>
<li>The non-porn files consisted mainly of people jumping around, trippy stuff, cartoon clips, cats and other animal antics ;0)</li>
</ul>
<p>I&#8217;ve archived everything that was uploaded to my local machine. Is there anything you&#8217;d like to know? Any ideas or suggested features?</p>
<p>update: For the moment, you can <a href="http://www.gifexplode.com/uploads/" target="_blank">browse what&#8217;s being uploaded</a> (lots NSFW). I will clear the contents of that directory every day or so, so don&#8217;t bother linking to the files there. A better way of sharing these gifs will come in a few months.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/08/gifexplode-community-powered-web-development/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Howard Yeend &#8211; UK Web Developer &#8211; PHP CV</title>
		<link>http://www.puremango.co.uk/2009/08/php-cv/</link>
		<comments>http://www.puremango.co.uk/2009/08/php-cv/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 13:40:52 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[(misc)]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[cv]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[howard]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[programmer]]></category>
		<category><![CDATA[resumé]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=217</guid>
		<description><![CDATA[Northampton / howard.yeend@gmail.com / 07790 816291 Availability Not currently seeking work. Sorry! (updated Aug 2010) Qualifications Oxford University 2008-2009 Subject: Computer Science MSc Result: Pass, distinction in dissertation. My dissertation focused on implementing Adaptive Web Sites using machine learning and Ajax. I passed modules including Object Oriented Programming with JAVA, Information Retrieval, Computational Linguistics and [...]]]></description>
			<content:encoded><![CDATA[<h6>Northampton / <a href="mailto:howard.yeend@gmail.com" target="_self">howard.yeend@gmail.com</a> / 07790 816291</h6>
<hr />
<p><span style="text-decoration: underline;"><strong>Availability</strong></span></p>
<p style="padding-left: 30px;">Not currently seeking work. Sorry! (updated Aug 2010)</p>
<p style="margin-top: 20px;"><strong><span style="text-decoration: underline;"><span id="more-217"></span>Qualifications</span><br />
</strong></p>
<p style="padding-left: 30px;"><strong>Oxford University <em>2008-2009</em></strong></p>
<p style="padding-left: 60px;"><strong>Subject:</strong><em> Computer Science MSc</em></p>
<p style="padding-left: 60px;"><strong>Result:</strong> <em>Pass, distinction in dissertation.</em></p>
<p style="padding-left: 60px;">My dissertation focused on implementing <a href="http://www.puremango.co.uk/2009/06/adaptive-web-sites/" target="_self">Adaptive Web Sites</a> using machine learning and Ajax. I passed modules including Object Oriented Programming with JAVA, Information Retrieval, Computational Linguistics and Compilers.</p>
<p style="padding-left: 30px;"><strong>University of Wales Lampeter <em>2004-2007</em></strong></p>
<p style="padding-left: 60px;"><strong>Subject:</strong> <em>Information Technology and Philosophical Studies BA</em></p>
<p style="padding-left: 60px;"><strong>Result:</strong> <em>First Class Honours, awarded Lampeter Society Prize for IT</em></p>
<p style="padding-left: 60px;">I undertook modules including SQL, Artificial Intelligence, Computer Modelling, Robotics and Ethics. My final project, a game, was written in VB.NET and MSSQL.</p>
<p style="padding-left: 30px;"><strong>Northampton College<em> 1999-2001</em></strong></p>
<p style="padding-left: 60px;">Distinction: City and Guilds &#8220;Computer Programming &#8211; Games &amp; Quizzes&#8221;</p>
<p style="padding-left: 60px;">Pass: City and Guilds &#8220;Computer Programming &#8211; Business Applications&#8221;</p>
<p style="padding-left: 30px;"><strong>Pitsford Independent School<em> 1995-1998</em></strong></p>
<p style="padding-left: 60px;">9 GCSEs: Physics (B), English Lit (B), English Lang (B), German (B), French (B), Maths (C), Chemistry (C), Biology (C), Geography (C).</p>
<p><strong><span style="text-decoration: underline;">Commercial Experience</span></strong></p>
<p style="padding-left: 30px;"><strong>GG.com / Twist Digital Media: <em>Feb 2010-current</em></strong></p>
<p style="padding-left: 60px;"><strong>Job Title:</strong> Web Developer</p>
<p style="padding-left: 60px;">Initially taken on board to help with the construction of a client&#8217;s website, I brought an idea for a new product to GG. Immediately seeing the potential, the company switched focus and direction around this idea. The product is now being developed by myself and other team members, is patent pending, and is being offered as a licensing deal to key players in our industry, and even has applications outside our domain. The client&#8217;s website was also delivered on time and to spec, enabling GG.com Ltd to meet their budgetary needs.</p>
<p style="padding-left: 60px;">Working day to day with solidly OO PHP 5, mySQL, HTML5 and cutting edge JavaScript (module pattern), jQuery, XUL and JSON, I am also involved with designing the new server architecture &#8211; my input is sought on how to use squid and memcache in conjunction with our existing hardware to implement a robust API server and CDN, not only for the high-traffic GG.com website but also for other products and web applications that the company offers.</p>
<p style="padding-left: 30px;"><strong>Web Office Systems: <em>Oct 2009-Feb 2010</em></strong></p>
<p style="padding-left: 60px;"><strong>Job Title:</strong> Web Developer</p>
<p style="padding-left: 60px;">Here I was responsible for developing and maintaining business oriented web applications and web services (SaaS) using PHP, mySQL, XML-RPC and Ajax, as well as performing routine linux server maintenance.</p>
<p style="padding-left: 30px;"><strong>GG.com / Twist Digital Media: </strong><strong><em>2007-2008 </em><br />
</strong></p>
<p style="padding-left: 60px;"><strong> Job Title:</strong> Web Developer</p>
<p style="padding-left: 60px;">Primarily developing in PHP 5/mySQL, this role was split 70/30 between maintaining existing systems and R&amp;D for new business directions. The company was looking to expand its web offerings with new in-browser betting games. I provided extensive input on technical feasibility for new projects, as well as being actively sought for my ideas for new business directions. During my time at GG, I redeveloped a javascript bet calculator which was deemed worthy of spinning off to a standalone website in its own right. I wrote a Firefox extension and Internet Explorer plugin for this calculator which allows people to use their sidebar to calculate bets while on other websites.</p>
<p style="padding-left: 30px;"><strong>Freetimers Ltd / Poulson Enterprises Group: </strong><em><strong>2001-2005</strong></em></p>
<p style="padding-left: 60px;"><strong> Job Titles:</strong> Internet Programmer, Senior Database Programmer</p>
<p style="padding-left: 60px;"><strong> </strong></p>
<p style="padding-left: 60px;">My role at Freetimers progressed rapidly from a junior technical role to being the primary designer and maintainer of the flagship product, Freedom<sup>TM</sup>. At Freetimers, I was instrumental in the design and continued development of all technical products now offered to clients. These products include a multi-lingual, multi-website content management system, a web-managed stock control system including ecommerce, and web-based bulk email software, as well as the multi-user admin shell.</p>
<p style="padding-left: 60px;">When I first started, Freetimers websites were produced from scratch on a per-client basis. My ideas and technical expertise allowed me to create standard, re-usable and upgradable modules that enabled Freetimers to massively reduce development time and continually improve the products offered to clients. I also managed a small number of junior developers, and brought their skill level forwards; under my supervision, a web graphics designer also became a html developer, and a html / PHP developer became a PHP / mySQL developer.</p>
<p><strong><span style="text-decoration: underline;">General IT Skills</span></strong></p>
<ul style="padding-left: 30px;">
<li>Standards-Compliant HTML / JavaScript / jQuery / dHTML / Ajax / JSON</li>
<li>Object Oriented PHP 5</li>
<li>MySQL</li>
<li>Excellent SEO ability; this resumé is ranked in the top results for &#8220;<a href="http://www.google.com/search?q=php+cv" target="_blank">php CV</a>&#8221; and &#8220;<a href="http://www.google.com/search?q=php+programmer+cv" target="_blank">php programmer CV</a>&#8220;.</li>
<li>Windows application development including C#, VB.NET, and NSIS.</li>
<li>Firefox addons, MSIE plugins, browser helper objects.</li>
<li>My GPL PHP CAPTCHA script was used by Apple and Mozilla, among others.</li>
<li>My work on CAPTCHA security has been cited by <a href="http://www.w3.org/TR/turingtest/" target="_blank">W3C</a>.</li>
<li>One of my PHP scripts has an average rating of 4½/5 from 100+ reviewers on <a href="http://www.hotscripts.com/listing/easygraph/#PublisherInfo" target="_blank">hotscripts.net</a>.</li>
<li>I have some experience with MSSQL/SQL Server and Linux server administration.</li>
</ul>
<p><strong><span style="text-decoration: underline;">Personal Statement</span></strong></p>
<p style="padding-left: 30px;">I am a highly motivated individual who thrives on interesting challenges and works best under pressure. I enjoy varied work and am deeply interested in all aspects of computer technology.</p>
<p style="padding-left: 30px;">My interests include machine learning, responsive UI design, and programming involving images. I also enjoy photography and science fiction. I am also a keen swimmer and collect robots and swiss army knives.</p>
<p style="padding-left: 30px;">In addition to <a href="http://www.puremango.co.uk" target="_self">puremango.co.uk</a>, I also maintain <a href="http://www.thingsinbooks.com" target="_self">thingsinbooks.com</a>, <a href="http://www.gifexplode.com" target="_blank">gifexplode.com</a> and <a href="http://www.geekwallpapers.com" target="_blank">geekwallpapers.com</a>.</p>
<p><em>References available on request.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/08/php-cv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP error handling</title>
		<link>http://www.puremango.co.uk/2009/07/php-error-handling/</link>
		<comments>http://www.puremango.co.uk/2009/07/php-error-handling/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 11:59:44 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[debug_backtrace]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[trigger_error]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=548</guid>
		<description><![CDATA[Does this type of error handling code look familiar? function doFunction&#40;$var&#41; &#123; if&#40;is_numeric&#40;$var&#41;&#41; &#123; /* do some stuff*/ &#125; else &#123; return -1; &#125; &#125; BLEH. How ugly is that? There&#8217;s no indication whether -1 is actually an error or a valid return value, or what it means. And other functions might use false to [...]]]></description>
			<content:encoded><![CDATA[<p>Does this type of error handling code look familiar?</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> doFunction<span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_numeric</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">/* do some stuff*/</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>BLEH. How ugly is that? There&#8217;s no indication whether -1 is actually an error or a valid return value, or what it means. And other functions might use false to indicate errors so there&#8217;s inconsistency. So I&#8217;ve written a very simple function to help you give meaningful PHP error messages.<br />
<span id="more-548"></span></p>
<p>Now, PHP already comes with a built-in function for reporting errors, called <a href="http://uk.php.net/manual/en/function.trigger-error.php" target="_blank">&#8220;trigger_error&#8221;</a>. But trigger_error always reports the line and file that trigger_error was called on. Which isn&#8217;t very useful.</p>
<p>For example:</p>
<p>main.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'functions.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'test'</span><span style="color: #339933;">;</span>
doFunction<span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// line 3</span></pre></div></div>

<p>functions.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> doFunction<span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_numeric</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">/* do some stuff*/</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'var must be numeric'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// line 5</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Because we&#8217;re using trigger_error, this will output something like this:</p>
<blockquote>
<p style="padding-left: 60px;"><strong>Notice</strong>:  var must be numeric in <strong></strong><strong>functions.php</strong> on line <strong>5</strong></p>
</blockquote>
<p>Which isn&#8217;t very useful, because really we&#8217;d want to know that main.php:3 was where the error was actually caused.</p>
<p>We&#8217;d really rather see something like this:</p>
<blockquote>
<p style="padding-left: 60px;"><strong>Notice</strong>:  var must be numeric in <strong>doFunction</strong> called from <strong>main.php</strong> on line <strong>3</strong></p>
</blockquote>
<p>Here&#8217;s a function to do just that:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> error<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #339933;">,</span> <span style="color: #000088;">$level</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">E_USER_NOTICE</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$caller</span> <span style="color: #339933;">=</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">debug_backtrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' in &lt;strong&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$caller</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'function'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/strong&gt; called from &lt;strong&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$caller</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'file'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/strong&gt; on line &lt;strong&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$caller</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'line'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/strong&gt;'</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&lt;br /&gt;error handler&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$level</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>So now in our example:</p>
<p>main.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'functions.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'test'</span><span style="color: #339933;">;</span>
doFunction<span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// line 3</span></pre></div></div>

<p>functions.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> doFunction<span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_numeric</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">/* do some stuff*/</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		error<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'var must be numeric'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// line 5</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #339933;">,</span> <span style="color: #000088;">$level</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">E_USER_NOTICE</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$caller</span> <span style="color: #339933;">=</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">debug_backtrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' in &lt;strong&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$caller</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'function'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/strong&gt; called from &lt;strong&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$caller</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'file'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/strong&gt; on line &lt;strong&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$caller</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'line'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/strong&gt;'</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&lt;br /&gt;error handler&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$level</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// line 11</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>now outputs:</p>
<blockquote>
<p style="padding-left: 60px;"><strong>Notice</strong>:  var must be numeric in <strong>doFunction</strong> called from <strong>main.php</strong> on line <strong>3</strong><br />
error handler in <strong>functions.php</strong> on line <strong>11</strong></p></blockquote>
<p>Isn&#8217;t that much nicer. Why yes, yes it is!</p>
<p>By the way, if you&#8217;re having trouble getting PHP to display error messages, try setting your php.ini&#8217;s error_reporting to E_STRICT (which you should be trying to adhere to anyway), or change $level to E_USER_WARNING</p>
<p>You can also use the E_USER_ERROR constant to halt the PHP interpreter.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/07/php-error-handling/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP 5.3.0 Released!</title>
		<link>http://www.puremango.co.uk/2009/07/php-5-3-0-released/</link>
		<comments>http://www.puremango.co.uk/2009/07/php-5-3-0-released/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 11:38:34 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[oop]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=543</guid>
		<description><![CDATA[If you&#8217;re still stuck in the old PHP 4 days, please please please take today&#8217;s release of PHP 5.3.0 as your cue to start learning about the wonderful world of object oriented PHP 5. 5.3.0 isn&#8217;t a hugely interesting release, but getting your PHP4 code compatible with 5 will ease the process when PHP 6 [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re still stuck in the old PHP 4 days, <em>please please please</em> take today&#8217;s release of PHP 5.3.0 as your cue to start learning about the wonderful world of object oriented PHP 5.</p>
<p>5.3.0 isn&#8217;t a hugely interesting release, but getting your PHP4 code compatible with 5 will ease the process when PHP 6 comes along. <strong>PHP6</strong> is really where it&#8217;s at:</p>
<p><strong>What&#8217;s out:</strong><br />
No more <strong>register_globals</strong> (finally)<br />
No more <strong>magic_quotes</strong> (you kinda liked magic quotes? Admittedly it was handy, but when you think about it, having code that <em>may or may not</em> be sanitised depending on a php.ini setting is a Bad Idea™)<br />
No more <strong>HTTP_GET_VARS</strong> and cousins. Just change to $_GET etc and you&#8217;re fine.</p>
<p><strong>What&#8217;s in:</strong><br />
A bunch of minor fixes aaand:<br />
Namespaces &#8211; so we can section off bits of code properly. Woohoo! <a href="http://php100.wordpress.com/2007/08/17/namespaces-faq/" target="_blank">more info here</a>.</p>
<p>Short post today I know, but I&#8217;ve got some real coding to do :) If you&#8217;re not doing anything better, go download PHP and have a play with it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/07/php-5-3-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Images Link Improver WordPress Plugin</title>
		<link>http://www.puremango.co.uk/2009/05/google-images-link-improver-wordpress-plugin/</link>
		<comments>http://www.puremango.co.uk/2009/05/google-images-link-improver-wordpress-plugin/#comments</comments>
		<pubDate>Fri, 01 May 2009 14:24:03 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=329</guid>
		<description><![CDATA[Google Images Link Improver improves the way visitors find your site by redirecting hits from google images to more relevant content on your blog. Here&#8217;s an example of how it works on an actual google images result for &#8220;earthrise&#8221;. The user clicks the following images result: &#8230; and here&#8217;s how the clickthrough page looks: Before [...]]]></description>
			<content:encoded><![CDATA[<p>Google Images Link Improver improves the way visitors find your site by redirecting hits from google images to more relevant content on your blog.</p>
<p>Here&#8217;s an example of how it works on an actual <a href="http://images.google.com/imgres?imgurl=http://aseattlephotographer.files.wordpress.com/2008/11/earthmoon_nasa.jpg&amp;imgrefurl=http://eyeshotjazz.wordpress.com/2008/11/&amp;usg=__zbFN50Ka7vO2i_YiAXP0v5bNe_A=&amp;h=600&amp;w=1267&amp;sz=117&amp;hl=en&amp;start=1&amp;um=1&amp;tbnid=T1cQr4c6em6jrM:&amp;tbnh=71&amp;tbnw=150&amp;prev=/images%3Fq%3Dearthrise%26hl%3Den%26sa%3DG%26um%3D1" target="_blank">google images result</a> for &#8220;earthrise&#8221;. The user clicks the following images result:<img class="aligncenter" src="/earthrise_gi.png" alt="" /><br />
&#8230; and here&#8217;s how the clickthrough page looks:</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="text-align: center;"><img src="/earth_before.png" alt="" /><br />
<strong> Before Plugin Installation</strong></td>
<td style="text-align: center;"><img src="/earth_after.png" alt="" /><br />
<strong>After Plugin Installation</strong></td>
</tr>
</tbody>
</table>
<p><span id="more-329"></span></p>
<p>Without the wordpress plugin installed, the user has to scroll through miles of content before they find the image they&#8217;re looking for &#8211; it&#8217;s very likely they&#8217;ll just leave in disgust.</p>
<p>With Google Images Link Improver, the user is shown the relevant image straight away, without ever even knowing they&#8217;ve been redirected!  Improve your search engine optimisation on google images, lower your bounce rate, connect searchers with your content :)</p>
<p><span style="font-size: 12pt;"><strong>Download the <a href="http://www.puremango.co.uk/google_images_link_improver.zip" target="_blank">Google Images Link Improver wordpress plugin.</a></strong></span></p>
<p><strong>Installation</strong></p>
<ol>
<li>Simply extract the zip file<sup> <a href="http://www.7-zip.org/" target="_blank">(how?)</a></sup> and upload the files to your wordpress blog<sup> <a href="http://fireftp.mozdev.org/" target="_blank">(how?)</a></sup>, in the following folder: /wp-content/plugins/<br />
<span style="color: white;">.</span></li>
<li>Now log in to your wordpress admin dashboard, and navigate to the plugins menu (yourdomain.com/wp-admin/plugins.php).<span style="color: white;">.</span><br />
Under &#8220;Inactive Plugins&#8221;, you&#8217;ll see an entry for &#8220;Google Images Link Improver&#8221;, something like this:<br />
<span style="color: white;">.</span><br />
<img src="/gili_plugin.png" alt="" /></li>
<li>Click &#8220;Activate&#8221;</li>
</ol>
<p><strong>That&#8217;s IT!</strong></p>
<p>Now when your blog recieves a hit from google images, the Google Images Link Improver wordpress plugin will examine the keywords and image filename from google images and redirect the user to the search page with those terms as the query, thus ensuring that the user is taken to the most relevant page on your blog.</p>
<p>There are some settings you can use to change the way Google Images Link Improver redirects users:</p>
<p>If the user searched Google Images for &#8220;cute puppy pictures&#8221; and found &#8220;bobby_the_wonder_dog_231.jpg&#8221; from your site, then:</p>
<ul style="list-style-type: disc;">
<li>Using <em>Original Google Query</em> &#8211; The user is taken to your search page with the query &#8220;cute puppy pictures&#8221;.</li>
<li>Using <em>Filename (exact)</em> &#8211; The user is taken to your search page with the query &#8220;bobby_the_wonder_dog_231&#8243;.</li>
<li>Using <em>Filename (as query)</em> &#8211; The user is taken to your search page with the query &#8220;bobby the wonder dog&#8221;.</li>
</ul>
<p>I recommend using <em>Filename (exact)<em>, </em></em>but you can adjust it to better suit your own blog.</p>
<p>If you find the plugin useful, why not write up a quick post about it, links are always appreciated! :D</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/05/google-images-link-improver-wordpress-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
