<?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>Dan Hulton&#039;s blog &#187; Coding</title>
	<atom:link href="http://www.danhulton.com/blog/category/coding/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.danhulton.com/blog</link>
	<description>Coffee, code, contemplation.</description>
	<lastBuildDate>Wed, 08 Sep 2010 03:31:22 +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>Initial Impressions of Komodo 6.0 Beta 2</title>
		<link>http://www.danhulton.com/blog/2010/07/16/initial-impressions-of-komodo-6-0-beta-2/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=initial-impressions-of-komodo-6-0-beta-2</link>
		<comments>http://www.danhulton.com/blog/2010/07/16/initial-impressions-of-komodo-6-0-beta-2/#comments</comments>
		<pubDate>Fri, 16 Jul 2010 16:58:44 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=299</guid>
		<description><![CDATA[Okay, honestly? I haven&#8217;t used it much, because of two pretty major issues that are blocking me: Can&#8217;t have multiple projects open at once In Komodo Edit 5.x, your &#8220;Projects&#8221; pane can have a bunch of projects listed in it, which is very useful &#8211; I tend to have a couple of projects open at [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, honestly?  I haven&#8217;t used it much, because of two pretty major issues that are blocking me:</p>
<h3>Can&#8217;t have multiple projects open at once</h3>
<p>In Komodo Edit 5.x, your &#8220;Projects&#8221; pane can have a bunch of projects listed in it, which is very useful &#8211; I tend to have a couple of projects open at once, so I can check in one project how I did something (or how an API works), and work in another project.  In IDE 6.x however, only one project is open at once, so I&#8217;d need to actually open the reference project, open the file, check it out, then switch back to my working project.  Tedious.</p>
<p>Worse, projects now keep track of what tabs you have open &#8211; so if I open one file file for reference, then switch to another project, I lose all my open tabs.</p>
<p>Definitely decreased functionality.  For this reason alone, I&#8217;d stay with Edit 5.x.</p>
<h3>&#8220;Project&#8221; pane and &#8220;Code&#8221; pane are both in the left pane</h3>
<p>I can either look at the files in my project or see the Code pane.  I need <b>both</b>.  I figured &#8220;easy, I&#8217;ll just switch the Code pane to the right&#8221; but no dice.  There&#8217;s no option for that.  No setting anywhere.  I looked throughout the install directory to boot, to see if there was something I could hack to get it usable, but nothing.  I can&#8217;t even have them BOTH open in the left pane (splitting the pane into two vertical sections).</p>
<p>Again, pretty much unusable.</p>
<p>I really want to like IDE 6.x, but these are pretty much showstoppers.  Thankfully 6.x is going to be in beta for &#8220;months more&#8221;, so with any luck things like this will get fixed, but I&#8217;m surprised they&#8217;re here in the first place.  Am I the <b>only</b> developer in the world who works from multiple projects at once and wants to see both files and code layout at the same time?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2010/07/16/initial-impressions-of-komodo-6-0-beta-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Kohana 3.0.7 is here!</title>
		<link>http://www.danhulton.com/blog/2010/07/12/kohana-3-0-7-is-here/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=kohana-3-0-7-is-here</link>
		<comments>http://www.danhulton.com/blog/2010/07/12/kohana-3-0-7-is-here/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 03:00:39 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=282</guid>
		<description><![CDATA[Earlier today, I was informed via Twitter that Kohana 3.0.7 had been released. &#8220;Great,&#8221; I thought. &#8220;Time to figure out what&#8217;s broken.&#8221; See, one of the strengths of Kohana is that the maintainers are totally willing to break backwards compatibility in order to refactor something a better way. However, one of the weaknesses of Kohana [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier today, I was informed via Twitter that <a href="http://twitter.com/KohanaPHP/status/18372659854">Kohana 3.0.7 had been released</a>.</p>
<p>&#8220;Great,&#8221; I thought.  &#8220;Time to figure out what&#8217;s broken.&#8221;</p>
<p>See, one of the strengths of Kohana is that the maintainers are totally willing to break backwards compatibility in order to refactor something a better way.  However, one of the weaknesses of Kohana is that the maintainers sneak in and break shit when they update.</p>
<p>It&#8217;s entirely the same thing, depending on how you look at it.  Thankfully, the devs rarely change anything sufficiently large enough to warrant more than a couple hours of bringing things up-to-code, and when I&#8217;m done <b>that</b> task, I generally end up with happier, nicer-looking code as a result.  So I can&#8217;t be too upset.</p>
<p>To boot, there&#8217;s usually some sweet ups along the way.  New functionality, enhanced functionality, broken stuff fixed, that kind of thing.  And while only a point-release, there&#8217;s some stuff in here this time that you very well may want to have.</p>
<h3>Two Whole New Modules!</h3>
<ul>
<li>The OAuth module lets you do neat things like integrate with Twitter without writing a lot of cruft code.</li>
<li>The UnitTest module integrates PHPUnit directly into Kohana!  This is so cool!  I played around a few times before with trying to do this myself before giving up on it in favour of writing actual domain code.  Now that someone more dedicated than myself has actually integrated it, who knows?  I might even start writing test cases.</li>
</ul>
<h3>Better XSS Protection!</h3>
<p>In all kinds of little places, characters are being escaped where they weren&#8217;t before, meaning that the XSS vulnerabilities that are in your project don&#8217;t creep in at the framework level.</p>
<h3>A Whole Bunch Of little Fixes!</h3>
<p>There seems to be generally better code documentation all over the place (example: the database config file), and a lot more flexibility opened up (example: final constructors removed all over the joint, the UTF8 file is now extensible).  As well, there&#8217;s a bunch of little bugs fixed everywhere, meaning that all those little edge cases I haven&#8217;t run up against?  I never will.</p>
<h3>So What Broke?</h3>
<p>Nothing!</p>
<p>Seriously, it just worked.  I copied 3.0.7&#8242;s system directly over 3.0.6&#8242;s.  Ditto for the auth and database modules.  This is perhaps one of the worst ways you can do an upgrade because so many things can go wrong, but nothing did.  I&#8217;m seriously impressed.</p>
<p>So there&#8217;s a couple of neat new things to play around with, a whole host of sweet little fixes &#8211; looks like a very solid update.</p>
<p>Kudos to the Kohana team!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2010/07/12/kohana-3-0-7-is-here/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Stupid(ly Useful) Kohana 3 Tricks &#8211; Safely Extending Base Classes</title>
		<link>http://www.danhulton.com/blog/2010/07/07/stupidly-useful-kohana-3-tricks-safely-extending-base-classes/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=stupidly-useful-kohana-3-tricks-safely-extending-base-classes</link>
		<comments>http://www.danhulton.com/blog/2010/07/07/stupidly-useful-kohana-3-tricks-safely-extending-base-classes/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 01:37:29 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=272</guid>
		<description><![CDATA[(Note: This post assumes a fairly high knowledge of how Kohana 3 works already. For a good tutorial, start here.) Kohana 3 has a very neat structure that allows you to safely extend its base classes, adding functionality to classes as core as Kohana itself without ruining the interfaces other classes use to communicate with [...]]]></description>
			<content:encoded><![CDATA[<p>(Note: This post assumes a fairly high knowledge of how Kohana 3 works already.  For a good tutorial, <a href="http://www.dealtaker.com/blog/2009/11/20/kohana-php-3-0-ko3-tutorial-part-1/">start here</a>.)</p>
<p>Kohana 3 has a very neat structure that allows you to safely extend its base classes, adding functionality to classes as core as Kohana itself without ruining the interfaces other classes use to communicate with it.</p>
<p>The basic pattern is as follows:</p>
<p><code>
<pre class="prettyprint">
abstract class Kohana extends Kohana_Core { }

class Kohana_Core {
    // Real functionality here
}
</pre>
<p></code></p>
<p>You may not recognize the brilliance inherent in this pattern if you don&#8217;t know a little something about Kohana &#8211; it autoloads classes in the following order:</p>
<p># Application folder, then<br />
# Module folders in the order defined in bootstrap.php, finally<br />
# System folder</p>
<p>Which means, if you define your own Kohana class in your application/classes folder, then anytime anyone calls Kohana::debug(), they&#8217;ll be calling YOUR version of Kohana.  Want to redefine debug() to output via <a href="http://www.firephp.org/">FirePHP?</a>  Go nuts.  Just make sure that your version of Kohana extends Kohana_Core.</p>
<p>But what if you&#8217;re developing a module, and you want people to be able extend &#8221;your&#8221; version of Kohana?  Well, you can follow the same pattern as the developers do:</p>
<p><code>
<pre class="prettyprint">
abstract class Kohana extends Kohana_Modulename { }

abstract class Kohana_Modulename extends Kohana_Modulename_Core {}

class Kohana_Modulename_Core extends Kohana_Core {
    // Real functionality here
}
</pre>
<p></code></p>
<p>It looks a little convoluted, but bear with me.  If people choose to define Kohana directly, they can, thus cutting off your module entirely.  But if people choose to extend from your module, they can define Kohana_Modulename and place their functionality in there, remembering to extend Kohana_Modulename_Core from that class, and the whole chain remains.  In fact, they can extend the chain further with this same pattern for their own Modulename.</p>
<p>Now, this doesn&#8217;t really help when two modules BOTH want to redefine Kohana and aren&#8217;t aware of each other, but that is probably always going to be a problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2010/07/07/stupidly-useful-kohana-3-tricks-safely-extending-base-classes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Naked Else &#8211; How I Hate Thee</title>
		<link>http://www.danhulton.com/blog/2009/06/25/the-naked-else-how-i-hate-thee/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=the-naked-else-how-i-hate-thee</link>
		<comments>http://www.danhulton.com/blog/2009/06/25/the-naked-else-how-i-hate-thee/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 19:24:20 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=170</guid>
		<description><![CDATA[I cannot express my frustration at seeing code like this: if (isset($modifier)) { // Do some things. // And some more things. // Still more // things // to be done here. // There's a whole lot of things here! // Last bunch of things } else { // Do totally different stuff } People. [...]]]></description>
			<content:encoded><![CDATA[<p>I cannot express my frustration at seeing code like this:</p>
<p><code>
<pre class="prettyprint">
if (isset($modifier)) {
    // Do some things.

    // And some more things.

    // Still more
    // things
    // to be done here.

    // There's a whole lot of things here!

    // Last bunch of things
}
else {
    // Do totally different stuff
}
</pre>
<p></code></p>
<p>People.  Comment your elses!  I shouldn&#8217;t have to scroll up to read the if again just to figure out what a branch of logic does.  This is a maintenance code nightmare, and simply adding a simple &#8220;// If validation has failed&#8221; will save all kinds of time and frustration.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2009/06/25/the-naked-else-how-i-hate-thee/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Super-useful Komodo Plugins</title>
		<link>http://www.danhulton.com/blog/2009/05/22/super-useful-komodo-plugins/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=super-useful-komodo-plugins</link>
		<comments>http://www.danhulton.com/blog/2009/05/22/super-useful-komodo-plugins/#comments</comments>
		<pubDate>Fri, 22 May 2009 18:33:02 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[jslint]]></category>
		<category><![CDATA[komodo edit]]></category>
		<category><![CDATA[lint]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[source tree]]></category>
		<category><![CDATA[todo]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=153</guid>
		<description><![CDATA[Komodo Edit is Awesome and has Plugins Komodo Edit is awesome and you should all use it. Seriously. I don&#8217;t know how much more I need to go on about this point, but the productivity benefits of a good IDE are astounding, and if you&#8217;re still using Notepad or gedit or the like like, then [...]]]></description>
			<content:encoded><![CDATA[<h3>Komodo Edit is Awesome and has Plugins</h3>
<p>Komodo Edit is awesome and you should all use it.</p>
<p>Seriously.  I don&#8217;t know how much more I need to go on about this point, but the productivity benefits of a good IDE are astounding, and if you&#8217;re still using Notepad or gedit or the like like, then you are Doing It Wrong.</p>
<p>If I had to recommend a good IDE, I&#8217;d recommend Komodo Edit.  I have before.  Hell, <a href="http://www.activestate.com/komodo_edit/">I&#8217;m still their go-to quote</a>, a fact that I find puzzling, yet rewarding.</p>
<p>Anyway.  The guys at Activestate switched to using the Mozilla codebase a while ago, which means that anyone who can write a Firefox extension can (in theory) write a Komodo extension.  And so they have!  And I have found three that I have fallen absolutely in love with.</p>
<p>They are:</p>
<h3><a href="http://community.activestate.com/node/1396">TODO Helper</a></h3>
<p>The <a href="http://community.activestate.com/node/1396">TODO Helper plugin</a> is great if you leave all kinds of little &#8220;TODO:&#8221;s scattered through your code as mental bookmarks.  This plug-in can quickly search your entire project for all TODOs listed and display them in the bottom panel.</p>
<p>It&#8217;s a little frustrating when the framework you&#8217;re using leaves TODOs in their releases, but it&#8217;s not hard to take those suckers out anyway.</p>
<h3><a href="http://community.activestate.com/xpi/kjslint-jslint-komodo">kJSLint</a></h3>
<p>A long while ago, I blogged about <a href="http://www.danhulton.com/blog/2008/01/16/integrate-js-lint-into-komodo-edit/">how to integrate jslint into Komodo Edit</a>, but I guess that&#8217;s not really strictly necessary these days.  Since there&#8217;s <a href="http://community.activestate.com/xpi/kjslint-jslint-komodo">a plugin that integrates jslint into a menu command</a>.</p>
<p>Sure, you lose out somewhat on the ability to control exactly what version of jslint you use, but the version included is rather up-to-date, and saves you the trouble of having to install an interpreter just to run it.  A definite win.</p>
<p>(Also, the &#8220;Crockford says no.&#8221; message it spits out when you fail validation makes me smile every time.)</p>
<h3>Source Tree</h3>
<p>Though not as slick as <a href="http://www.activestate.com/komodo_edit/osx_sections_list_code.jpg">Komodo IDE&#8217;s code browser</a>, at least the <a href="http://community.activestate.com/xpi/source-tree">Source Tree plugin</a> is free and does what it says on the tin.  Having the entirety of the file&#8217;s functions and classes available and easy to navigate is <em>very</em> handy.  Shame this isn&#8217;t in the free version of Edit to start, but they&#8217;ve got to have <em>some</em> features to differentiate the two enough to encourage people to buy the &#8220;pro&#8221; edition.</p>
<h3>And in Conclusion</h3>
<p>Komodo Edit.  It&#8217;s good.  Komodo Edit with Plugins.  Even better.</p>
<p>Now get coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2009/05/22/super-useful-komodo-plugins/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Clean Code: Nested conditionals</title>
		<link>http://www.danhulton.com/blog/2009/05/12/cleaning-up-your-code-nested-conditionals/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=cleaning-up-your-code-nested-conditionals</link>
		<comments>http://www.danhulton.com/blog/2009/05/12/cleaning-up-your-code-nested-conditionals/#comments</comments>
		<pubDate>Tue, 12 May 2009 19:58:13 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=65</guid>
		<description><![CDATA[Ugly code is everywhere. Inside that copy of Microsoft Office 2007, behind that latest Linux kernel, and in the dozens and dozens of web 2.0 MicroISV tools you use day-in and day out. Lurking. But there are those of us who fight! Who rage against the dying of the light! Those who are more than [...]]]></description>
			<content:encoded><![CDATA[<p>Ugly code is everywhere.  Inside that copy of Microsoft Office 2007, behind that latest Linux kernel, and in the dozens and dozens of web 2.0 MicroISV tools you use day-in and day out.  Lurking.</p>
<p>But there are those of us who fight!  Who rage against the dying of the <a href="#" title="elegant and maintanable code">light</a>!  Those who are more than happy to share our solutions to cleaning up ugly code, in the hopes that up-and-coming programmers will notice and apply said solutions.  This&#8230; is one such solution.</p>
<p>Take, for example, nested conditions.  They look like:</p>
<p><code>
<pre class="prettyprint">
if (thing) {
    [CHUNK A]
    if (thing) {
        [CHUNK B]
        if (thing) {
            [CHUNK C]
        }
    }
}
</pre>
<p></code></p>
<p>It&#8217;s not THAT ugly, but try extending that out into five or more chunks, or if you&#8217;ve already indented a couple of times, you will notice just how ugly this looks.  Since each chunk is only executed based on the result of a boolean test (the if statements), and each chunk is directly dependant on the previous chunk (and oughn&#8217;t be run if the previous chunk fails), we can take advantage of short-circuit operators and rewrite this section of code to be much cleaner.</p>
<p>Instead, rewrite each chunk into its own function, have that function return a boolean, and you can rewrite the original code like:</p>
<p><code>
<pre class="prettyprint">
$success = do_chunk_a();
$success = $success &#038;&#038; do_chunk_b();
$success = $success &#038;&#038; do_chunk_c();
</pre>
<p></code></p>
<p>This is a <em>huge</em> win in terms of readability, and therefore in terms of maintainability.  Especially so if you name your new functions descriptively, like &#8220;send_invoice()&#8221; or &#8220;update_client_list()&#8221;.  It&#8217;s far easier to look at the descriptive name of the functions instead of having to read through the entirety of each chunk, just to find out what the code is supposed to <em>do</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2009/05/12/cleaning-up-your-code-nested-conditionals/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>New in PHP 5.3</title>
		<link>http://www.danhulton.com/blog/2009/04/06/new-in-php-53/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=new-in-php-53</link>
		<comments>http://www.danhulton.com/blog/2009/04/06/new-in-php-53/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 21:23:26 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[lambdas]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqlnd]]></category>
		<category><![CDATA[namespaces]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ternary]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=116</guid>
		<description><![CDATA[PHP is approaching another important release, version 5.3. The release candidate is already available, if you&#8217;re interested in trying things out early. I thought I&#8217;d take a moment however, and highlight four really interesting new features we can expect in this new release. 1) Namespaces Adding namespaces solves, in a stroke, a great many conflicts [...]]]></description>
			<content:encoded><![CDATA[<p>PHP is approaching another important release, version 5.3.  <a href="http://www.php.net/archive/2009.php#id2009-03-24-1">The release candidate is already available</a>, if you&#8217;re interested in trying things out early.  I thought I&#8217;d take a moment however, and highlight four really interesting new features we can expect in this new release.</p>
<h2>1) <a href="http://ca.php.net/namespaces">Namespaces</a></h2>
<p>Adding namespaces solves, in a stroke, a great many conflicts that developers tend to run into with PHP.  For example, if I write a database layer class called db and YOU write a database layer called db, and I try to include another library that you&#8217;ve written that references your database layer, I&#8217;m boned.  Since they&#8217;re both declared globally, this attempt at code re-use fails.</p>
<p>However, if I write a database layer and I decide to put it in the &#8220;danhulton&#8221; namespace, and you put yours in the &#8220;anotherlibrary&#8221; namespace, we&#8217;re fine.  I refer to &#8220;danhulton\db&#8221; and you refer to &#8220;anotherlibrary\db&#8221; and all is right in the world.</p>
<p>Sadly, the namespace delimiter they&#8217;ve chosen is the backslash, which to my eyes just looks ODD, and also can run you into issues if you ever have to put your namespace in a string (with backslash being the escape character).  Still, this is a net win for writing shareable PHP code.</p>
<h2>2) <a href="http://docs.php.net/functions.anonymous">Anonymous Functions</a></h2>
<p>I got into the habit of using anonymous functions liberally in javascript, and have come to sorely miss them in PHP.  Sure, you can emulate them with create_function(), but the syntax is awkward and the resource cost prohibitive.  As of PHP 5.3, we&#8217;ll be able do do something a little like this:</p>
<pre class="prettyprint"><code>$escaped = array_map(function($value) {
    return "'" . $value . "'";
}, array('sql', 'parameters', 'that', 'need', 'escaping'));</code></pre>
<p>I&#8217;m very much looking forward to the cleaner code this will allow me to produce.</p>
<h2>3) <a href="http://ca.php.net/ternary#language.operators.comparison.ternary">Ternary (?:) Operator</a></h2>
<p>The ternary operator already exists in PHP, and I use it frequently.  It allows you to do something like this:</p>
<pre class="prettyprint"><code>$colour = ($balance > 0) ? 'green' : 'red';</code></pre>
<p>Or, if you need to ensure a value is set before using it, you can write:</p>
<pre class="prettyprint"><code>$entries = isset($entries) ? $entries : array();</code></pre>
<p>In PHP 5.3, you&#8217;ll be able to simply write:</p>
<pre class="prettyprint"><code>$entries = $entries ?: array();</code></pre>
<p>Which means you can also write:</p>
<pre class="prettyprint"><code>foreach ($entries ?: array() as $entry) {
    // some stuff
}</code></pre>
<p>This change is excellent because, again, it leads to cleaner code.</p>
<h2>4) <a href="http://ca3.php.net/mysqli.mysqlnd">Native MySQL library driver</a></h2>
<p>This should be a huge win for many applications which value efficiency.  (Although, isn&#8217;t that all of them?)  The MySQL native driver is a full replacement for the currently-used driver written my MySQL AB.  It is more efficient in terms of memory usage (storing all rows only once instead of twice), and should be just as processor-friendly, if not more.  Further, there are a host of performance statistics calls that should ensure that performance debugging is much easier, and they include a function I wish had been there from the beginning: <a href="http://ca3.php.net/manual/en/mysqli-result.fetch-all.php">mysqli_fetch_all()</a>.  No more having to write a big while() loop with mysql_fetch_assoc(), this baby will take care of you in one line.</p>
<p>Now, since I&#8217;ve switched to the <a href="http://kohanaphp.com/">Kohana framework</a>, my database functions are a lot friendlier already, so the latter function won&#8217;t specifically change how I code.  But the decreased memory costs, especially for queries that return many rows, will be fantastic.</p>
<h2>Conclusion</h2>
<p>PHP 5.3 is going to be an excellent addition to the language, one I can&#8217;t wait for.  I expect a fair amount of grumbling as we get adjusted to all the new features, and I&#8217;m rather curious to see what Kohana and other frameworks decide to do with regard to support (ideally for Kohana, IMHO, is keep KO 2.3 compatable with PHP 5.2.9, but require PHP 5.3 for KO 2.4 and 3.0).  However, in the long run, we&#8217;ll have the ability to write cleaner, clearer, and <em>less</em> code, and that will be a fantastic advantage.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2009/04/06/new-in-php-53/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sharing cookies between subdomains in Kohana PHP</title>
		<link>http://www.danhulton.com/blog/2009/01/01/sharing-cookies-between-subdomains-in-kohana-php/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=sharing-cookies-between-subdomains-in-kohana-php</link>
		<comments>http://www.danhulton.com/blog/2009/01/01/sharing-cookies-between-subdomains-in-kohana-php/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 00:12:12 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[kohana]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sessions]]></category>
		<category><![CDATA[subdomains]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=81</guid>
		<description><![CDATA[So i&#8217;m working on a little side-project again, and something cropped up that kept me occupied for about an hour. I have a subdomain for logging in, and from there, users are redirected to personalized subdomains. By default, cookies aren&#8217;t shared between subdomains, but there are various ways around that. At a basic level, the [...]]]></description>
			<content:encoded><![CDATA[<p>So i&#8217;m working on a little side-project again, and something cropped up that kept me occupied for about an hour.  I have a subdomain for logging in, and from there, users are redirected to personalized subdomains.  By default, cookies aren&#8217;t shared between subdomains, but there are various ways around that.</p>
<p>At a basic level, the domain for the cookie is typically set to &#8220;www.yourdomain.com&#8221;.  So if you have users redirected to &#8220;premium.yourdomain.com&#8221;, they lose their cookies because their domain no longer matches.  If you set the domain for your cookies to &#8220;.yourdomain.com&#8221; however, cookies set in one subdomain will match and carry over to other subdomains.</p>
<p>You can set this via php.ini, in your .htaccess files, through an ini_set() call, or even through a session_set_cookie_params() call.  However, if you&#8217;re using Kohana (as I am), what you <em>actually</em> need to do is to copy system/config/cookie.php to application/config/cookie.php and modify the domain parameter to match the following:</p>
<pre><code>$config['domain'] = substr($_SERVER['SERVER_NAME'],
                           strpos($_SERVER['SERVER_NAME'], '.'),
                           100);</code></pre>
<p>This way, no matter what server name you&#8217;re using (development or live), the right cookie domain is set.</p>
<p>One final thing to keep in mind when you&#8217;ve implemented this little solution &#8211; don&#8217;t forget to clear your cookies!  I spent a further twenty minutes thinking I&#8217;d missed something code-wise because Firefox still had a better-qualified cookie left over from before and was relying on that instead of my sparklin&#8217; new &#8220;.yourdomain.com&#8221; cookie.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2009/01/01/sharing-cookies-between-subdomains-in-kohana-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FireStick 1.0 &#8211; Performance logging add-on library for CodeIgniter</title>
		<link>http://www.danhulton.com/blog/2008/09/22/firestick-10-performance-logging-add-on-library-for-codeigniter/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=firestick-10-performance-logging-add-on-library-for-codeigniter</link>
		<comments>http://www.danhulton.com/blog/2008/09/22/firestick-10-performance-logging-add-on-library-for-codeigniter/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 20:36:21 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[benchmarking]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[firestick]]></category>
		<category><![CDATA[gpl]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/?p=57</guid>
		<description><![CDATA[From the announcement post on the CodeIgniter forums: FireStick is a (relatively) simple to configure library that enables easy and low-overhead performance logging in CodeIgniter. Performance measuring and logging is an important part of application maintenance and improvement. FireStick makes it easy to record page render times, MySQL call times, and other related information that [...]]]></description>
			<content:encoded><![CDATA[<p>From the <a href="http://codeigniter.com/forums/viewthread/91696/">announcement post on the CodeIgniter forums</a>:</p>
<blockquote><p>FireStick is a (relatively) simple to configure library that enables easy and low-overhead performance logging in CodeIgniter. </p>
<p>Performance measuring and logging is an important part of application maintenance and improvement.  FireStick makes it easy to record page render times, MySQL call times, and other related information that you can use to track down performance issues. </p>
<p>FireStick relies on CodeIgniter’s built-in performance and benchmarking capabilities and a post-system hook.  When the hook is called, FireStick logs all this information to the database for review at a later date. </p>
<p>Logs are split up into multiple tables based on date, with each new day’s table created automatically on the first request of each new day.  All logs are added using INSERT DELAYED so as to minimize impact on the database server. </p>
<p>Main project page: <a href="http://code.google.com/p/firestick/">http://code.google.com/p/firestick/</a><br />
Project source: <a href="http://firestick.googlecode.com/files/firestick-1.0.zip">http://firestick.googlecode.com/files/firestick-1.0.zip</a><br />
Installation instructions: <a href="http://code.google.com/p/firestick/wiki/Installation">http://code.google.com/p/firestick/wiki/Installation</a></p></blockquote>
<p>I&#8217;ve been reading <a href="http://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/0596101716/ref=pd_bbs_sr_1?ie=UTF8&#038;s=books&#038;qid=1222115234&#038;sr=1-1">High Performance MySQL</a> lately, and the very first section of the book is on profiling, why it&#8217;s a good idea, and how to go about doing it.  Since I&#8217;ve deployed <a href="http://www.danhulton.com/comingup/">ComingUp</a> out in the wild, I figured <em>I</em> should be profiling, too.</p>
<p>So I put together this little add-on library for CodeIgniter that takes the basics presented in the text and adapts them to CodeIgniter&#8217;s already well-rounded benchmark system.  CodeIgniter already has total script execution time measured, total script memory consumption, and a full list of all DB calls and the amount of time they took.  I just collated all of that and put it into a sensible DB logging system.</p>
<p>The whole deal is open source, too.  GPL v3.  Any CodeIgniter developer anywhere can feel free to use this, and I&#8217;d be happy if they did.</p>
<p>If you are using it, and you encounter any bugs or want to provide feedback, please leave a comment in <a href="http://codeigniter.com/forums/viewthread/91696/">the FireStick thread on the CodeIgniter forums</a>, and I&#8217;ll be happy to address it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2008/09/22/firestick-10-performance-logging-add-on-library-for-codeigniter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Writing a Good Bug Report</title>
		<link>http://www.danhulton.com/blog/2008/01/21/writing-a-good-bug-report/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=writing-a-good-bug-report</link>
		<comments>http://www.danhulton.com/blog/2008/01/21/writing-a-good-bug-report/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 15:02:53 +0000</pubDate>
		<dc:creator>Dan Hulton</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[bug reports]]></category>
		<category><![CDATA[bugs]]></category>

		<guid isPermaLink="false">http://www.danhulton.com/blog/2008/01/21/writing-a-good-bug-report/</guid>
		<description><![CDATA[A bad bug report can be worse than no bug report. A bad bug report leads to frustrated developers, which leads to developers marking bugs as &#8220;Cannot Reproduce&#8221; and sending it back, which leads to bug tennis, where the developer and the QA tester whip the bug back and forth to each other, crying &#8220;It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>A bad bug report can be worse than no bug report.  A bad bug report leads to frustrated developers, which leads to developers marking bugs as &#8220;Cannot Reproduce&#8221; and sending it back, which leads to bug tennis, where the developer and the QA tester whip the bug back and forth to each other, crying &#8220;It&#8217;s broken!&#8221; and &#8220;No, it&#8217;s not!&#8221; all day.  Good bug reports require only a little more effort to produce and make lives an order of magnitude easier for everyone in QA and development.</p>
<p>As an example of just how bad things can get, here&#8217;s an example of a terrible bug report:</p>
<blockquote><p>I make an order and click Next but get told error about not supporting billing.</p></blockquote>
<p>As a developer looking to test that bug, I would have absolutely no idea how to start.  I&#8217;ve likely submitted dozens of orders already and none of them have failed, least of all with some ambiguous error regarding the billing system.  This is the kind of hair-pulling complaint I expect to see from my Mom when she&#8217;s having trouble buying from Amazon or setting up online banking.</p>
<p>Bug reports absolutely require 4 pieces of information:</p>
<ol>
<li>Summary</li>
<li>Steps to reproduce</li>
<li>What you expected to see</li>
<li>What you actually saw</li>
</ol>
<p>Let&#8217;s examine them individually.</p>
<h3>1) Summary</h3>
<p>Anyone scanning through long lists of bugs need to be able to instantly identify what a bug is about, so the summary has to be concise and uniquely identify the bug in question.  Try to limit to 80 characters or less as a guideline.  Avoid the urge to go into detail here &#8211; this can be included in the actual bug report itself.</p>
<p>Example: &#8220;Cannot submit Mastercard transactions with card expiration dates after 08/11&#8243;</p>
<h3>2) Steps to reproduce</h3>
<p>This is probably the most critical part of the bug report.  A bug that can&#8217;t be found can&#8217;t be fixed, and a bug without listed repro steps is <strong>very</strong> hard to find.  Provide these steps in an ordered list, ensuring that they are easy to follow and contain ALL information required to reproduce the bug, including setup steps that need to be taken to trigger it (like turning an option on or off).</p>
<p>Example:</p>
<ol>
<li>Add Pink Cat Collar #3444 to cart.</li>
<li>Click check-out button.</li>
<li>Use development Mastercard (3557) with expiration date 08/12 to submit transaction.</li>
</ol>
<h3>3) What you expected to see</h3>
<p>What you should have seen if there was no bug.</p>
<p>Example: &#8220;Order complete/receipt page.&#8221;</p>
<h3>4) What you actually saw</h3>
<p>What you saw due to the bug.  If the program spits out any debug information, copy/paste it into your bug report.  If it&#8217;s over 20 lines long, or if you need to include an entire HTML page or file, include it as an attachment.</p>
<p>Example: &#8220;PHP Error: &#8216;Line 42: Overflow in $cardChecksum&#8217;&#8221;</p>
<h3>Optional &#8211; Further description</h3>
<p>If you have more stuff to say about the bug than what&#8217;s listed above, don&#8217;t try to mash it into the fields above.  Place it under the header &#8220;Additional Information&#8221; or similar.  If you can find conditions the bug suspiciously <strong>doesn&#8217;t</strong> happen under, list them here.  Don&#8217;t muddy the waters with ideas on how to fix the bug here, unless you&#8217;re <strong>absolutely certain</strong> you know what&#8217;s wrong.  Your job is not to be the doctor and diagnose, but to be the patient and report symptoms.</p>
<p>Sloppy writing and conjecture isn&#8217;t encouraged anywhere in a bug report, but the one place you can get away with it is in the &#8220;Further description&#8221; field &#8211; provide as much information as you think is relevant.  Developers would far prefer to have to read extra material than have to hunt you down to figure out just what your bug report meant.</p>
<h3>Optional &#8211; Severity/Priority</h3>
<p>The severity or priority of a bug indicates how damaging it is to the product.  A properly set severity level is important, as often, bugs can either be fixed or not fixed based on a set schedule, and the severity level is used to identify which fixes make it in and which don&#8217;t.  QA Testers are rarely the people who set severity levels of bugs, but I find they&#8217;re so often misunderstood that covering them here would probably help.</p>
<p>There are many schools of thought on how to properly categorize severity levels, but in the interests of brevity I&#8217;ll just cover one, a fairly common 5-level classification:</p>
<ul>
<li><img style="background-color: #fff; border: 2px solid #7B5D1A; float: left;" src='http://www.danhulton.com/blog/wp-content/uploads/2008/01/priority_blocker.gif' alt='Severity level: Blocker' /> Blocker &#8211; Blocks development or testing.  Examples: Installer doesn&#8217;t work/application fails to launch.</li>
<li style="clear: left;"><img style="background-color: #fff; border: 2px solid #7B5D1A; float: left;" src='http://www.danhulton.com/blog/wp-content/uploads/2008/01/priority_critical.gif' alt='Severity level: Critical' /> Critical &#8211; Loss of data, crashes, public exposure of private data.  Examples: Renaming an account deletes it, listing the credit cards on your account lists all credit cards on all accounts.</li>
<li style="clear: left;"><img style="background-color: #fff; border: 2px solid #7B5D1A; float: left;" src='http://www.danhulton.com/blog/wp-content/uploads/2008/01/priority_major.gif' alt='Severity level: Major' /> Major &#8211; Major loss of function, or function loss where no work-around exists.  Examples: Layering function in a graphics editor doesn&#8217;t work, or unable to change font in a text editor.</li>
<li style="clear: left;"><img style="background-color: #fff; border: 2px solid #7B5D1A; float: left;" src='http://www.danhulton.com/blog/wp-content/uploads/2008/01/priority_minor.gif' alt='Severity level: Minor' /> Minor &#8211; Minor loss of function, or function loss wher an easy work-around exists.  Examples: &#8220;Close&#8221; button on tabs don&#8217;t work, but Menu->Close does, italics doesn&#8217;t work with little-used font.</li>
<li style="clear: left;"><img style="background-color: #fff; border: 2px solid #7B5D1A; float: left;" src='http://www.danhulton.com/blog/wp-content/uploads/2008/01/priority_trivial.gif' alt='Severity level: Trivial' /> Trivial &#8211; Cosmetic problem that does not impede functionality.  Examples: &#8220;Exit when finished&#8221; translates to &#8220;Please leave now&#8221; in Korean, where you sell five units a year, border around statistics doesn&#8217;t show up under certain browsers.</li>
</ul>
<p>Keep in mind that <em>severity</em> doesn&#8217;t necessarily equate to <em>priority</em>, and these are typically separate fields in many bug tracking systems.  A Critical bug that affects only one customer worth $200/month should definately have a lower priority than a Major bug that affects multiple customers worth multiple thousands.</p>
<h3>Summary</h3>
<p>The aim of the bug report is to make the failure you encountered as instantly obvious to the developer assigned to fix it as it is to you.  Approach the whole thing <i>scientifically</i>.  If I follow the same steps as you followed, I should get the same result, on which we can build (i.e. fix).  You should aim to be specific and clear about what you&#8217;re reporting (never &#8220;it&#8221; or &#8220;the textbox&#8221;, use &#8220;the cursor&#8221; or &#8220;the address textbox&#8221; instead), concise in your summary and repro steps, and accurate.</p>
<p>With only a little more effort and attention paid to including the right information, you can turn a rushed, bad bug report into a thoughtful, good bug report.  Your developers will thank you, your managers will thank you, heck, Amnesty International will probably thank you.  Okay, well maybe not, but still, it&#8217;s a good idea.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhulton.com/blog/2008/01/21/writing-a-good-bug-report/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
