<?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>Bradley Holt &#187; PHP</title>
	<atom:link href="http://bradley-holt.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://bradley-holt.com</link>
	<description></description>
	<lastBuildDate>Thu, 17 May 2012 01:04:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>The MVC Paradox</title>
		<link>http://bradley-holt.com/2012/04/the-mvc-paradox/</link>
		<comments>http://bradley-holt.com/2012/04/the-mvc-paradox/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 17:27:23 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Domain-Driven Design]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Slim]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Web Application Frameworks]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1503</guid>
		<description><![CDATA[Use of the Model View Controller (MVC) design pattern is generally accepted as a best practice in modern web applications. Like all design patterns, MVC is a reusable solution to a common problem. The MVC pattern is intended to address the following concerns: Support for multiple types of clients Reduce duplicate code when supporting multiple [...]]]></description>
			<content:encoded><![CDATA[<p>Use of the Model View Controller (MVC) design pattern is generally accepted as a best practice in modern web applications. Like all design patterns, MVC is a reusable solution to a common problem. The MVC pattern is intended to address the following concerns:</p>
<ol>
<li>Support for multiple types of clients</li>
<li>Reduce duplicate code when supporting multiple types of clients</li>
<li>Isolating domain logic from the user interface</li>
</ol>
<p>Note that items 2 and 3 are both dependent on item 1. <em>Support for multiple types of clients is the single driving force behind the MVC design pattern.</em> Following are some examples of client types:</p>
<ul>
<li>Web Browsers</li>
<li>API Clients</li>
<li>Admin Processes (e.g. CLI, cron, daemon)</li>
<li>Unit Tests</li>
<li>Native GUI</li>
</ul>
<p>Realistically, how many of these different client types do you need to support? If you&#8217;re taking a RESTful approach, then <a href="http://caines.ca/blog/programming/the-sun-is-setting-on-rails-style-mvc-frameworks/">Web Browsers and API Clients can be combined into one type of client</a>, which we can just call User Agents. Likely you&#8217;re not building a Native GUI. This leaves you with the following three types of clients to support:</p>
<ul>
<li>User Agents</li>
<li>Admin Processes</li>
<li>Unit Tests</li>
</ul>
<p>Do you really need to use the MVC design pattern in order to support User Agents, Admin Processes, and Unit Tests? Likely not. That&#8217;s not to say that there aren&#8217;t benefits to isolating domain logic from the user interface. However, if you don&#8217;t need to support multiple types of clients you should really question your use of the MVC design pattern. There are many approaches one can take to separating the domain logic and the user interface, of which MVC is just one.</p>
<p>This bring me to The MVC Paradox.<em> Modern MVC web frameworks inadvertently encourage the coupling of domain logic and user interface.</em> If you don&#8217;t need to support multiple types of clients, then decoupling the domain logic from the user interface is the only reason left to use the MVC design pattern.</p>
<p>Modern MVC web frameworks often involve a lot of boilerplate code just to support the primary client type of User Agents. This boilerplate code typically does little to help with supporting the other client types of Admin Processes and Unit Tests. As a result of the overhead introduced by this extra boilerplate code, developers often find themselves creating Fat Controllers (a side-effect of The MVC Paradox). Controllers take on too many responsibilities, both vertically and horizontally. Vertically, Controllers start to handle domain logic that should be pushed down to the Model layer. Horizontally, multiple concerns get stuffed into a handful of Controllers. These different horizontal concerns should be separated out into multiple Controllers (the Single Responsibility Principle). The overhead introduced by modern MVC web frameworks leads directly to these problems.</p>
<p>In contrast, take a look at the <a href="http://www.slimframework.com/">Slim PHP 5 micro framework</a>. While not a completely <a href="http://www.developerfusion.com/article/141194/evaluating-rest-frameworks-part-1-a-maturity-model/">RESTful framework</a>, it does a pretty good job of addressing the concerns I&#8217;ve laid out in this post. Here is the &#8220;Hello world&#8221; example from Slim&#8217;s homepage:</p>
<pre><code class="php">&lt;?php
require 'Slim/Slim.php';
$app = new Slim();
$app-&gt;get('/hello/:name', function ($name) {
    echo "Hello, $name!";
});
$app-&gt;run();
?&gt;</code></pre>
<p>There is very little boilerplate code involved in handling a User Agent&#8217;s request. Minting and handling new routes is incredibly simple. Placing your entire front-end application layer in one file may seem absurd at first. However, it has the nice side-effect of making it painfully obvious if you start to handle domain logic outside of your Model layer or if one route is doing too many things. If your front-end application is large enough, then you can <a href="http://www.slimframework.com/read/how-to-organize-a-large-slim-framework-application">organize your routes into separate files</a>.</p>
<p>This post is not intended to discourage you from using an MVC web framework. There are certainly times when such a framework is useful. As with any technology decision, carefully consider what problem you&#8217;re trying to solve and what technology will best address your problem set. Sometimes your technology choice can undermine the very purpose of using that technology in the first place, as is the case with The MVC Paradox.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2012/04/the-mvc-paradox/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Boston PHP Northeast Conference Call for Papers Closing!</title>
		<link>http://bradley-holt.com/2012/04/boston-php-northeast-conference-call-for-papers-closing/</link>
		<comments>http://bradley-holt.com/2012/04/boston-php-northeast-conference-call-for-papers-closing/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 20:25:04 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Boston]]></category>
		<category><![CDATA[Boston PHP]]></category>
		<category><![CDATA[btvphp]]></category>
		<category><![CDATA[btvphpug]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1498</guid>
		<description><![CDATA[The Boston PHP Northeast Conference&#8217;s Call for Papers will be closing on Thursday, April 12th so be sure to get your talk submissions in before then! The conference will be taking place on Saturday, August 11th and Sunday, August 12th at Microsoft’s NERD Center in Cambridge, MA and will be focused around four tracks: Core [...]]]></description>
			<content:encoded><![CDATA[<p>The Boston PHP Northeast Conference&#8217;s <a href="http://speakers.northeastphp.org/">Call for Papers</a> will be closing on Thursday, April 12<sup>th</sup> so be sure to get your talk submissions in before then! The conference will be taking place on Saturday, August 11<sup>th</sup> and Sunday, August 12<sup>th</sup> at <a href="http://microsoftcambridge.com/">Microsoft’s NERD Center</a> in Cambridge, MA and will be focused around four tracks:</p>
<ul>
<li>Core PHP</li>
<li>Web Development</li>
<li>Training</li>
<li>User Experience (UX)</li>
</ul>
<p><a href="http://www.bostonphp.org/">Boston PHP</a> will be hosting the event in partnership with other northeast regional user groups including the <a href="http://groups.google.com/group/burlington-vt-php">Burlington, Vermont PHP Users Group</a> (which I organize) and the <a href="http://acphpug.paladin-bs.com/">Atlantic Canadian PHP User Group</a>. If you have any questions or are interested in sponsoring then please <a href="http://www.meetup.com/bostonphp/suggestion/">send a message to Boston PHP</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2012/04/boston-php-northeast-conference-call-for-papers-closing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top Five Posts of 2011</title>
		<link>http://bradley-holt.com/2011/12/top-five-posts-of-2011/</link>
		<comments>http://bradley-holt.com/2011/12/top-five-posts-of-2011/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 17:15:32 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AMQP]]></category>
		<category><![CDATA[CouchApp]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Domain-Driven Design]]></category>
		<category><![CDATA[FOSS]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[Open Standards]]></category>
		<category><![CDATA[OSCON]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP-QAT]]></category>
		<category><![CDATA[Quality Assurance]]></category>
		<category><![CDATA[RabbitMQ]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Scaling]]></category>
		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1480</guid>
		<description><![CDATA[Continuing a trend started by Cal Evans and then followed by Chris Cornutt, Matthew Turland, and Joe Devon; here are the top five most viewed posts from my blog in 2011. 5. CouchDB and Domain-Driven Design This post covered two topics that are of great interest to me. Document databases like CouchDB have much potential [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing a trend started by <a href="http://blog.calevans.com/2011/12/29/top-three-posts-of-2011/">Cal Evans</a> and then followed by <a href="http://blog.phpdeveloper.org/?p=425">Chris Cornutt</a>, <a href="http://matthewturland.com/2011/12/29/top-10-posts-of-2011/">Matthew Turland</a>, and <a href="http://mysqltalk.wordpress.com/2011/12/30/top-posts-of-2011/">Joe Devon</a>; here are the top five most viewed posts from my blog in 2011.</p>
<h3>5. <a href="http://bradley-holt.com/2011/08/couchdb-and-domain-driven-design/">CouchDB and Domain-Driven Design</a></h3>
<p>This post covered two topics that are of great interest to me. Document databases like CouchDB have much potential when it comes to domain-driven design. The post outlined some techniques for serializing domain objects into CouchDB documents.</p>
<h3>4. <a href="http://bradley-holt.com/2011/07/addressing-the-nosql-criticism/">Addressing the NoSQL Criticism</a></h3>
<p>I heard a lot of NoSQL bashing this year at OSCON. As a result, I decided to write a rebuttal to many of the criticisms that I heard. This post inspired a lively <a href="http://bradley-holt.com/2011/07/addressing-the-nosql-criticism/#comments">comment thread</a>.</p>
<h3>3. <a href="http://bradley-holt.com/2011/07/testing-php-5-4/">Testing PHP 5.4</a></h3>
<p>This was a short post on how to help the <a href="http://qa.php.net/">PHP Quality Assurance Team</a> by running the tests for the latest development version of PHP 5.4. It covered downloading, compiling, and running the tests. Most importantly, it also covered reporting your test results.</p>
<h3>2. <a href="http://bradley-holt.com/2011/07/exploring-rabbitmq-and-php/">Exploring RabbitMQ and PHP</a></h3>
<p>I was exploring the possibility of using RabbitMQ for an upcoming project. I decided to post some notes on my experience getting started with RabbitMQ and integrating it with PHP. I haven&#8217;t ended up using RabbitMQ in production yet, but I&#8217;m confident that I&#8217;ll end up using it at some point.</p>
<h3>1. <a href="http://bradley-holt.com/2011/07/couchdb-jquery-plugin-reference/">CouchDB jQuery Plugin Reference</a></h3>
<p>I had been frustrated by the lack of documentation for the CouchDB jQuery plugin—so decided to write my own. After I wrote the blog post, <a href="http://www.maxogden.com/">Max Ogden</a> pointed me to <a href="http://arandomurl.com/">Dale Harvey</a>‘s <a href="https://github.com/daleharvey/jquery.couch.js-docs">documentation generator for jquery.couch.js</a> and a copy of the generated <a href="http://daleharvey.github.com/jquery.couch.js-docs/symbols/index.html">jQuery CouchDB documentation</a>. Max and Dale are also working on a more flexible jquery.couch2.js.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/12/top-five-posts-of-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Boston PHP Northeast Conference</title>
		<link>http://bradley-holt.com/2011/12/boston-php-northeast-conference/</link>
		<comments>http://bradley-holt.com/2011/12/boston-php-northeast-conference/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 15:41:44 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Boston]]></category>
		<category><![CDATA[Boston PHP]]></category>
		<category><![CDATA[btvphpug]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1473</guid>
		<description><![CDATA[I&#8217;m excited to be able to announce that the first ever Boston PHP Northeast Conference will be taking place on Saturday, August 11th and Sunday, August 12th at Microsoft&#8217;s NERD Center in Cambridge, MA. This regional event is intended for PHP beginners, enthusiasts, and professionals alike. The current plan is to have four tracks: Core [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m excited to be able to announce that the first ever Boston PHP Northeast Conference will be taking place on Saturday, August 11<sup>th</sup> and Sunday, August 12<sup>th</sup> at <a href="http://microsoftcambridge.com/">Microsoft&#8217;s NERD Center</a> in Cambridge, MA. This regional event is intended for PHP beginners, enthusiasts, and professionals alike. The current plan is to have four tracks:</p>
<ul>
<li>Core PHP</li>
<li>Web Development</li>
<li>Training</li>
<li>User Experience (UX)</li>
</ul>
<p><a href="http://www.bostonphp.org/">Boston PHP</a> will be hosting the event in partnership with other northeast regional user groups including the <a href="http://groups.google.com/group/burlington-vt-php">Burlington, Vermont PHP Users Group</a> (which I organize) and the <a href="http://acphpug.paladin-bs.com/">Atlantic Canadian PHP User Group</a>. We&#8217;re still early in the planning stages, so there will be more details to come later. If you&#8217;re interested in speaking, have ideas for the event, or are interested in sponsoring then please <a href="http://www.meetup.com/bostonphp/suggestion/">send a message to Boston PHP</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/12/boston-php-northeast-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Twelve-Factor App Applied to PHP</title>
		<link>http://bradley-holt.com/2011/11/the-twelve-factor-app-applied-to-php/</link>
		<comments>http://bradley-holt.com/2011/11/the-twelve-factor-app-applied-to-php/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 16:31:02 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software Deployment]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Twelve-Factor App]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1451</guid>
		<description><![CDATA[If you develop web apps, I encourage you to check out The Twelve-Factor App. This is an excellent resource for anyone building and deploying software-as-a-service. PHP has great support for many of the twelve-factors. I want to take a look at specifically how each factor may be applied to a PHP application. I. Codebase &#8220;One [...]]]></description>
			<content:encoded><![CDATA[<p>If you develop web apps, I encourage you to check out <a href="http://www.12factor.net/">The Twelve-Factor App</a>. This is an excellent resource for anyone building and deploying software-as-a-service. PHP has great support for many of the twelve-factors. I want to take a look at specifically how each factor may be applied to a PHP application.</p>
<h3>I. <a href="http://www.12factor.net/codebase">Codebase</a></h3>
<blockquote><p>&#8220;One codebase tracked in revision control, many deploys&#8221;</p></blockquote>
<p>There&#8217;s really not much here that would be different in PHP versus any other language. Who isn&#8217;t using some form of revision control these days?</p>
<h3>II. <a href="http://www.12factor.net/dependencies">Dependencies</a></h3>
<blockquote><p>&#8220;Explicitly declare and isolate dependencies&#8221;</p></blockquote>
<p>There are a few tools available to PHP developers to help manage dependencies. The <a href="http://pear.php.net/">PEAR</a> package manager may help here, but has its flaws. <a href="http://pear2.php.net/PEAR2_Pyrus">Pyrus</a>, the PEAR2 package manager, looks promising. There&#8217;s also <a href="http://packagist.org/about-composer">Composer</a>. I&#8217;ve heard of people using their operating system&#8217;s package manager (e.g. RPM) to deploy their PHP applications and manage dependencies. I&#8217;m not sure if there any tools in PHP to enforce <em>dependency isolation</em>.</p>
<h3>III. <a href="http://www.12factor.net/config">Config</a></h3>
<blockquote><p>&#8220;Store config in the environment&#8221;</p></blockquote>
<p>The simplest option here is to use <em>environment variables</em>. Many frameworks, including Zend Framework, allow you to have environment-specific configuration such as <code>development</code>, <code>test</code>, and <code>production</code>. This is not recommended for twelve-factor apps as it doesn&#8217;t scale as new environments are added.</p>
<h3>IV. <a href="http://www.12factor.net/backing-services">Backing Services</a></h3>
<blockquote><p>&#8220;Treat backing services as attached resources&#8221;</p></blockquote>
<p>There&#8217;s not really anything to say here that&#8217;s specific to PHP.</p>
<h3>V. <a href="http://www.12factor.net/build-release-run">Build, release, run</a></h3>
<blockquote><p>&#8220;Strictly separate build and run stages&#8221;</p></blockquote>
<p><a href="http://www.phing.info/trac/">Phing</a> or the more general-purpose <a href="http://ant.apache.org/">Ant</a> could work here. Even though it&#8217;s not written in PHP, there&#8217;s no reason why you couldn&#8217;t use <a href="https://github.com/capistrano/capistrano/wiki">Capistrano</a> for this. I don&#8217;t think the <em>run stage</em> typically applies to PHP, as it happens implicitly as part of the <em>release stage</em>. However, there are tasks such as flushing the APC cache (if <code>apc.stat=0</code>) that might be considered part of the <em>run stage</em>.</p>
<h3>VI. <a href="http://www.12factor.net/processes">Processes</a></h3>
<blockquote><p>&#8220;Execute the app as one or more stateless processes&#8221;</p></blockquote>
<p>PHP processes are already stateless and <a href="http://en.wikipedia.org/wiki/Shared_nothing_architecture">shared-nothing</a>. This makes PHP a great fit for twelve-factor apps. Memory space or the filesystem should be used as a short-lived, single-process cache. If you&#8217;re using an asset manager, such as <a href="https://github.com/kriswallsmith/assetic">Assetic</a>, then any assets should be compiled and cached during the <a href="http://www.12factor.net/build-release-run">build stage</a>.</p>
<h3>VII. <a href="http://www.12factor.net/port-binding">Port binding</a></h3>
<blockquote><p>&#8220;Export services via port binding&#8221;</p></blockquote>
<p>I don&#8217;t think port binding applies to PHP applications—at least not in the way it&#8217;s meant in twelve-factor. PHP relies on a web server and uses something like <a href="http://www.fastcgi.com/">FastCGI</a> or <a href="http://php-fpm.org/">PHP-FPM</a> to communicate with the web server. PHP 5.4 will have its own built-in web server, but this is intended for development use only. It&#8217;s really the combination of PHP and its web server that will be bound to a port. This brings up challenges when it comes to dependency management, as the web server itself is now a dependency.</p>
<h3>VIII. <a href="http://www.12factor.net/concurrency">Concurrency</a></h3>
<blockquote><p>&#8220;Scale out via the process model&#8221;</p></blockquote>
<p>I&#8217;m not sure how processes would become first-class citizens in a PHP web application. However, each individual request/response cycle is handled by its own process. In that regard, PHP already uses the process model.</p>
<h3>IX. <a href="http://www.12factor.net/disposability">Disposability</a></h3>
<blockquote><p>&#8220;Maximize robustness with fast startup and graceful shutdown&#8221;</p></blockquote>
<p>PHP processes are very disposable. Again, this is just part of how PHP works.</p>
<h3>X. <a href="http://www.12factor.net/dev-prod-parity">Dev/prod parity</a></h3>
<blockquote><p>&#8220;Keep development, staging, and production as similar as possible&#8221;</p></blockquote>
<p>Nothing specific to PHP here. Although, it&#8217;s not uncommon for PHP developers to use SQLite in development and MySQL or PostgreSQL in production. This is not recommended for a twelve-factor app—use the same software and versions of <a href="http://www.12factor.net/backing-services">backing services</a> in all environments.</p>
<h3>XI. <a href="http://www.12factor.net/logs">Logs</a></h3>
<blockquote><p>&#8220;Treat logs as event streams&#8221;</p></blockquote>
<p>There are tons of logging options in PHP. <a href="http://framework.zend.com/manual/en/zend.log.writers.html#zend.log.writers.stream"><code>Zend_Log_Writer_Stream</code></a> lets you send log data to a <a href="http://www.php.net/stream">PHP stream</a>. Alternatively, <a href="http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/">StatsD and the PHP StatsD library</a> look pretty good.</p>
<h3>XII. <a href="http://www.12factor.net/admin-processes">Admin processes</a></h3>
<blockquote><p>&#8220;Run admin/management tasks as one-off processes&#8221;</p></blockquote>
<p>This is easy enough in PHP. If you want an interactive shell with readline history, tab completion, and quick access to documentation then check out <a href="http://www.phpsh.org/">phpsh</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/11/the-twelve-factor-app-applied-to-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Case For Rapid Release Cycles</title>
		<link>http://bradley-holt.com/2011/08/the-case-for-rapid-release-cycles/</link>
		<comments>http://bradley-holt.com/2011/08/the-case-for-rapid-release-cycles/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 20:02:14 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Release Management]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1303</guid>
		<description><![CDATA[There has been some discussion recently on the Zend Framework mailing list around release cycles. I proposed a release cycle of six months for major versions (someone else suggested eighteen months, which may be more reasonable for a framework). Rapid releases allow one to accelerate the cycle of building, measuring, and learning. Gathering data from [...]]]></description>
			<content:encoded><![CDATA[<p>There has been some discussion recently on the Zend Framework mailing list around release cycles. I proposed a release cycle of six months for major versions (someone else suggested eighteen months, which may be more reasonable for a framework). Rapid releases allow one to accelerate the cycle of building, measuring, and learning. Gathering data from actual usage (measuring) provides an opportunity for learning that can be applied to the next release (building).</p>
<p>Zend Framework 2.0 should be released soon, and it has been four years since the last major release (1.0). This is not to imply that Zend Framework has been stagnant—far from it. There has been a ton of development effort and many improvements to Zend Framework since 1.0. I have a great amount of trust in the team, and I have complete confidence that Zend Framework 2.0 will be an awesome framework. This post is intended to make the case for rapid release cycles for software in general, and is not meant to be a criticism of Zend Framework or the development processes behind it. However, the discussions around Zend Framework&#8217;s release cycle are what&#8217;s prompting me to make this post.</p>
<p>First, let me describe what I mean by a &#8220;rapid release cycle&#8221;. In this context, I mean rapid releases of major versions. Put simply, major versions are those that allow backwards compatible breaks. This is somewhat controversial. I don&#8217;t think anyone really has any big concerns with the rapid release of minor (introduction of new features while maintaining backwards compatibility) or maintenance (bug and/or security fix) releases. &#8220;Rapid&#8221; depends on the context. Both Chrome and Firefox have adopted a six-week release cycle. As I mentioned before, six months could be considered &#8220;rapid&#8221; for a framework.</p>
<p>For a framework (and maybe for other software), I think the following rules are necessary in order for a rapid release cycle to work:</p>
<ul>
<li>Minimize backwards compatibility changes between major releases. Targeted and strategic refactoring, rather than major overhauls, are preferable if you are releasing often. Small backwards compatibility changes makes migrating from one major version to another much easier.</li>
<li>Mark some major releases as &#8220;Long Term Support&#8221; (LTS) releases. Provide bug fix updates and security patches to these releases for three to five years. This provides a &#8220;safe&#8221; option to those who value stability and don&#8217;t want to upgrade very often. In the context of Zend Framework, it is obviously Zend&#8217;s decision if they want to take on this burden. If not, then I don&#8217;t think a rapid release cycle is viable.</li>
</ul>
<p>What are the concerns with a rapid release cycle? I&#8217;ll paraphrase, and then address, the major concerns that I&#8217;ve heard.</p>
<p>&#8220;Rapid releases of major versions are just for psychological effect and has no affect on the delivery pace of new features.&#8221; This is both true and false. See my earlier post on <a href="http://bradley-holt.com/2011/07/iterative-vs-incremental/">iterative vs. incremental development</a>. If development is incremental and driven entirely by a pre-determined roadmap then there is no tangible differences between a &#8220;normal&#8221; and a rapid release cycle. The development of many consumer software packages is perceived as incremental, in which case major version bumps <em>are</em> mostly psychological. However, if you take an iterative development approach and build-in outside learning from end-users into your process, then a rapid release cycle gives you the chance to change course based on outside feedback. Learning opportunities are introduced that you would have never had if your software wasn&#8217;t actually used by real people in the real world.</p>
<p>&#8220;Rapid release cycles are for consumer software where you don&#8217;t have to care for backward compatibility.&#8221; This is related to the previous concern. My response is that rapid release cycles are for any product where learning from real-world usage and outside input can be used to improve the product. To quote <a href="http://steveblank.com/">Steve Blank</a>, &#8220;There are no answers inside the building.&#8221;</p>
<p>&#8220;It forces people to upgrade too often and rewrite their code, or get left behind.&#8221; See my earlier note about minimizing backwards compatibility changes in each major release. Additionally, it is much easier to automate upgrades if the backwards compatibility changes are small. There should be little code rewriting for applications built using the framework with each major version upgrade of the framework.</p>
<p>&#8220;Having lots of end-of-life (EOL) versions being used could be a security risk.&#8221; See my earlier note about providing LTS releases. Each major release should come with a pre-determined EOL date. It is the responsibility of the end-user (in the case of a framework, the developer) to be aware of a release&#8217;s EOL date. Using EOLed software is always a security risk.</p>
<p>While not specifically a concern with rapid release cycles, there&#8217;s a general mentality that major releases are &#8220;our chance to get it right.&#8221; Hopefully you&#8217;re a better software developer than you were even six months ago. Chances are you know more than you did then, and would approach solving problems differently now. Think six months before that, and six months before that. Now project this into the future. Where will you be in six months? Will you know more than you do now? Will you approach solving problems differently than you do now? If you&#8217;re a good software developer, you will never get it &#8220;right&#8221;—you will always be better six months from now than you are today and know more than you know today. A rapid release cycle allows you to apply new learning, knowledge, and perspective as often as possible. Do your best today, and give yourself opportunities to do your best in the future as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/08/the-case-for-rapid-release-cycles/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Propose a Session for Vermont Code Camp 2011</title>
		<link>http://bradley-holt.com/2011/08/propose-a-session-for-vermont-code-camp-2011/</link>
		<comments>http://bradley-holt.com/2011/08/propose-a-session-for-vermont-code-camp-2011/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 16:58:04 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[BTV]]></category>
		<category><![CDATA[FOSS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Vermont]]></category>
		<category><![CDATA[vtcc3]]></category>
		<category><![CDATA[vtcodecamp]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1294</guid>
		<description><![CDATA[Vermont is a beautiful place to visit—especially in the fall! We&#8217;re looking for Vermonters and non-Vermonters alike to speak at this year&#8217;s Vermont Code Camp. Vermont Code Camp is organized entirely by community volunteers, with the help of our great sponsors (we&#8217;re still accepting sponsorships, too). Vermont Code Camp is a polyglot event. We&#8217;re looking [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://vtcodecamp.org/"><img class="alignright size-full wp-image-722" title="Vermont Code Camp" src="http://bradley-holt.com/wp-content/uploads/2010/07/Vermont-Code-Camp-gradient-250x96.png" alt="Vermont Code Camp" width="250" height="96" /></a>Vermont is a beautiful place to visit—especially in the fall! We&#8217;re looking for Vermonters and non-Vermonters alike to <a href="http://vtcodecamp.org/propose-a-session/">speak at this year&#8217;s Vermont Code Camp</a>. Vermont Code Camp is organized entirely by community volunteers, with the help of our great <a href="http://vtcodecamp.org/sponsors/">sponsors</a> (we&#8217;re still accepting sponsorships, too). Vermont Code Camp is a polyglot event. We&#8217;re looking for sessions on .NET, PHP, Ruby, Python, Java, and more. <a href="http://vtcodecamp.org/propose-a-session/">Abstracts are due this Friday, August 12</a> and we&#8217;re going to try and have the <a href="http://vtcodecamp.org/schedule/">session list</a> available by August 19. Check out the <a href="http://vtcodecamp.org/2010-schedule/">2010 schedule</a> to get an idea of what we had for talks last year.</p>
<p>Personally, I&#8217;d like to encourage submissions on the following topics:</p>
<ul>
<li>More talks related to free/open source software (PHP, Ruby, Python, etc.)</li>
<li>Arduino and/or other hardware programming</li>
<li>Software development patterns and practices</li>
<li>Web analytics and metrics</li>
<li>Front-end web development (JavaScript, CSS, etc.)</li>
<li>Node.js and other emerging technologies</li>
<li>Mobile application development</li>
<li>Anything you&#8217;re passionate about!</li>
</ul>
<p><a href="http://vtcodecamp.org/propose-a-session/">Propose a session or two now</a>—you know you want to!</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/08/propose-a-session-for-vermont-code-camp-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CouchDB and Domain-Driven Design</title>
		<link>http://bradley-holt.com/2011/08/couchdb-and-domain-driven-design/</link>
		<comments>http://bradley-holt.com/2011/08/couchdb-and-domain-driven-design/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 15:30:27 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Domain-Driven Design]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1251</guid>
		<description><![CDATA[I&#8217;ve found CouchDB to be a great fit for domain-driven design (DDD). Specifically, CouchDB fits very well with the building block patterns and practices found within DDD. Two of these building blocks include Entities and Value Objects. Entities are objects defined by a thread of continuity and identity. A Value Object &#8220;is an object that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve found CouchDB to be a great fit for <a href="http://en.wikipedia.org/wiki/Domain-driven_design">domain-driven design</a> (DDD). Specifically, CouchDB fits very well with the building block patterns and practices found within DDD. Two of these building blocks include <em><a href="http://domaindrivendesign.org/node/109">Entities</a></em> and <em><a href="http://domaindrivendesign.org/node/135">Value Objects</a></em>. Entities are objects defined by a thread of continuity and identity. A Value Object &#8220;is an object that describes some characteristic or attribute but carries no concept of identity.&#8221; Value objects should be treated as immutable.</p>
<p><em><a href="http://domaindrivendesign.org/node/88">Aggregates</a></em> are groupings of associated Entities and Value Objects. Within an Aggregate, one member is designated as the <em>Aggregate Root</em>. External references are limited to only the Aggregate Root. Aggregates should follow transaction, distribution, and concurrency boundaries. Guess what else is defined by transaction, distribution, and concurrency boundaries? That&#8217;s right, JSON documents in CouchDB.</p>
<p>Let&#8217;s take a look at an example Aggregate, that representing a blog entry and related metadata. Note that the following UML diagrams are for classes in PHP, but it should be easy enough to translate these examples to any object-oriented programming language. We&#8217;ll start with the <code>Entry</code> Entity, which will serve as our Aggregate Root:</p>
<pre>-----------------------------------------
|                 Entry                 |
-----------------------------------------
|+ id : string                          |
|+ rev : string                         |
|+ title : Text                         |
|+ updated : Date                       |
|+ authors : Person[*]                  |
|+ content : Text                       |
-----------------------------------------
|+ __construct(entry : array) : void    |
|+ toArray() : array                    |
-----------------------------------------</pre>
<p>The <code>Text</code> Value Object:</p>
<pre>----------------------------------------------
|                    Text                    |
----------------------------------------------
|- type : string                             |
|- text : string                             |
----------------------------------------------
|+ __construct(type : string, text : string) |
|+ toArray() : array                         |
----------------------------------------------</pre>
<p>The <code>Date</code> Value Object:</p>
<pre>--------------------------------------
|                Date                |
--------------------------------------
|- timestamp : integer               |
--------------------------------------
|+ __construct(timestamp : integer)  |
|+ __toString() : string             |
--------------------------------------</pre>
<p>The <code>Person</code> Value Object:</p>
<pre>-------------------------------------------------------------
|                           Person                          |
-------------------------------------------------------------
|- name : string                                            |
|- uri : string                                             |
|- email : string                                           |
-------------------------------------------------------------
|+ __construct(name : string, uri : string, email : string) |
|+ toArray() : array                                        |
-------------------------------------------------------------</pre>
<p>I recommend serializing each Aggregate, starting with the Aggregate  Root, into a JSON document. Control access to Aggregate Roots  through a <em><a href="http://domaindrivendesign.org/node/123">Repository</a></em>. The <code>toArray()</code> methods above return an associative array representation of each object. The Repository can then transform the array into JSON for storage in CouchDB. Let&#8217;s take a look at the <code>EntryRepository</code>:</p>
<pre>---------------------------------
|        EntryRepository        |
---------------------------------
|                               |
---------------------------------
|+ get(id : string) : Entry     |
|+ post(entry : Entry) : void   |
|+ put(entry : Entry) : void    |
|+ delete(entry : Entry) : void |
---------------------------------</pre>
<p>Here&#8217;s an example of what the Aggregate&#8217;s object graph might look like, serialized as a JSON document:</p>
<pre><code class="javascript">{
    "_id": "http://bradley-holt.com/?p=1251",
    "title": {
        "type": "text",
        "text": "CouchDB and Domain-Driven Design"
    },
    "updated": "2011-08-02T15:30:00+00:00",
    "authors": [
        {
             "name": "Bradley Holt",
             "uri": "http://bradley-holt.com/",
             "email": "bradley.holt@foundline.com"
        }
    ],
    "content": {
        "type": "html",
        "text": "&lt;p&gt;I've found CouchDB to be a great fit for…&lt;/p&gt;"
    }
}</code></pre>
<p>You can also provide access to CouchDB views through Repositories. In the above example, this could be through the addition of an <code>index(skip : integer, limit : integer) : Entry[*]</code> method to the the <code>EntryRepository</code> (note that this is a naive pagination implementation, especially on large data sets—but that&#8217;s beyond the scope of this blog post). For more complex views, you may want to create a separate Repository for each CouchDB view.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/08/couchdb-and-domain-driven-design/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Exploring RabbitMQ and PHP</title>
		<link>http://bradley-holt.com/2011/07/exploring-rabbitmq-and-php/</link>
		<comments>http://bradley-holt.com/2011/07/exploring-rabbitmq-and-php/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 22:10:38 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AMQP]]></category>
		<category><![CDATA[FOSS]]></category>
		<category><![CDATA[Open Standards]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1179</guid>
		<description><![CDATA[I&#8217;m exploring the possibility of using RabbitMQ for an upcoming project. RabbitMQ is a free/open source message broker platform. It uses the open Advanced Message Queuing Protocol (AMQP) standard and is written in Erlang using the Open Telecom Platform (OTP). It promises a high level of availability, throughput, scalability, and portability. Since it is built [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m exploring the possibility of using <a href="http://www.rabbitmq.com/">RabbitMQ</a> for an upcoming project. RabbitMQ is a free/open source message broker platform. It uses the open <a href="http://www.amqp.org/">Advanced Message Queuing Protocol</a> (AMQP) standard and is written in <a href="http://www.erlang.org/">Erlang using the Open Telecom Platform</a> (OTP). It promises a high level of availability, throughput, scalability, and portability. Since it is built using open standards, it is interoperable with other messaging systems and can be accessed from any platform.</p>
<p>I&#8217;ll be using RabbitMQ first from PHP, but I plan on using it to send and receive messages to and from other systems. Following are the steps I used to get RabbitMQ and PHP&#8217;s AMQP library setup on my development machine.</p>
<p>First, I installed RabbitMQ using MacPorts:</p>
<pre><code class="no-highlight">$ sudo port install rabbitmq-server</code></pre>
<p>Then, I started RabbitMQ:</p>
<pre><code class="no-highlight">$ sudo rabbitmq-server -detached</code></pre>
<p>Next, I installed the <a href="http://hg.rabbitmq.com/rabbitmq-c/">librabbitmq</a> library using a slight variation of the instructions on <a href="http://www.php.net/manual/en/amqp.installation.php">PHP&#8217;s AMQP Installation</a> page (you may need to install <a href="http://mercurial.selenic.com/">Mercurial</a> first):</p>
<pre><code class="no-highlight">$ hg clone http://hg.rabbitmq.com/rabbitmq-c/rev/3c549bb09c16 rabbitmq-c
$ cd rabbitmq-c
$ hg clone http://hg.rabbitmq.com/rabbitmq-codegen/rev/f8b34141e6cb codegen
$ autoreconf -i &amp;&amp; ./configure &amp;&amp; make &amp;&amp; sudo make install</code></pre>
<p>Then, I installed the AMQP extension using PECL:</p>
<pre><code class="no-highlight">$ sudo pecl install amqp-beta</code></pre>
<p>To test that everything works, I opened up two interactive PHP shells using <code>php -a</code>. I ran the following code in the first PHP shell:</p>
<pre><code class="php">$exchangeName = 'messages';
$routeKey = 'routeA';
$message = 'Hello, world.';
$connection = new AMQPConnection();
$connection-&gt;connect();
$exchange = new AMQPExchange($connection);
$exchange-&gt;declare($exchangeName);
</code></pre>
<p>I then ran the following code in the second PHP shell:</p>
<pre><code class="php">$exchangeName = 'messages';
$routeKey = 'routeA';
$connection = new AMQPConnection();
$connection-&gt;connect();
$queue = new AMQPQueue($connection);
$queue-&gt;declare($exchangeName);
$queue-&gt;bind($exchangeName, $routeKey);</code></pre>
<p>Back in the first PHP shell:</p>
<pre><code class="php">$exchange-&gt;publish($message, $routeKey);</code></pre>
<p>Back in the second PHP shell:</p>
<pre><code class="php">$message = $queue-&gt;get();
print_r($message);</code></pre>
<p>Here is the output I got from the print_r statement:</p>
<pre><code class="php">Array
(
    [routing_key] =&gt; routeA
    [exchange] =&gt; messages
    [delivery_tag] =&gt; 1
    [Content-type] =&gt; text/plain
    [count] =&gt; 0
    [msg] =&gt; Hello, world.
)</code></pre>
<p>There are several other options that can be set, and a lot more to learn about RabbitMQ and AMP. Check out the <a href="http://www.php.net/manual/en/book.amqp.php">documentation for PHP&#8217;s AMQP extension</a> for details about working with AMQP servers from PHP.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/07/exploring-rabbitmq-and-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Testing PHP 5.4</title>
		<link>http://bradley-holt.com/2011/07/testing-php-5-4/</link>
		<comments>http://bradley-holt.com/2011/07/testing-php-5-4/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 20:05:46 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[FOSS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP-QAT]]></category>
		<category><![CDATA[Quality Assurance]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1125</guid>
		<description><![CDATA[Rasmus Lerdorf today posted instructions for testing the upcoming PHP 5.4 release. Running the PHP tests and submitting the associated report will help the PHP team get PHP 5.4 ready faster as it gives them reports of failed tests from a variety of platforms. I just did this today for the first time and can [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://toys.lerdorf.com/">Rasmus Lerdorf</a> today posted <a href="http://codepad.org/SXfRlJ0w">instructions for testing the upcoming PHP 5.4 release</a>. Running the PHP tests and submitting the associated report will help the PHP team get PHP 5.4 ready faster as it gives them reports of failed tests from a variety of platforms. I just did this today for the first time and can tell you that it is very easy. Following are the steps that Rasmus outlined, in a bit more detail.</p>
<p>First, make sure that you have <code>subversion</code>, <code>autoconf</code>, <code>automake</code>, <code>gcc</code>, <code>bison</code>, <code>flex</code>, and <code>re2c</code> installed. I&#8217;m using a Mac, so I was able to install most of these using MacPorts (Homebrew would have worked, too). Next, do a checkout of the PHP 5.4 branch:</p>
<pre><code class="bash">$ svn co https://svn.php.net/repository/php/php-src/branches/PHP_5_4 php54</code></pre>
<p>Then:</p>
<pre><code class="bash">$ cd php54
$ ./buildconf
$ ./configure
$ make
$ make test</code></pre>
<p>Both the <code>make</code> and <code>make test</code> steps may take awhile. Assuming you get some failed tests like I did, then you will see the following message and prompt:</p>
<pre><code class="no-highlight">You may have found a problem in PHP.
This report can be automatically sent to the PHP QA team at
http://qa.php.net/reports and http://news.php.net/php.qa.reports
This gives us a better understanding of PHP's behavior.
If you don't want to send the report immediately you can choose
option "s" to save it.    You can then email it to qa-reports@lists.php.net later.
Do you want to send this report now? [Yns]:</code></pre>
<p>I opted to send the report now, so entered <code>Y</code>. Next, I was prompted for my email address:</p>
<pre><code class="no-highlight">Please enter your email address.
(Your address will be mangled so that it will not go out on any
mailinglist in plain text):</code></pre>
<p>I entered my email address and then:</p>
<pre><code class="no-highlight">Posting to http://qa.php.net/buildtest-process.php

Thank you for helping to make PHP better.</code></pre>
<p>Pretty straightforward. At this point, your report should be aggregated on the <a href="http://qa.php.net/reports/">PHP Test Reports Summary</a> page. If you want to run more tests, then configure as many extensions as possible during the configure step. Take a look at the <a href="http://codepad.org/SXfRlJ0w">shell script in Rasmus&#8217; instructions</a> for details. If you&#8217;d like, you can examine the failed tests and see if you can come up with a patch to fix the problem. Again, see <a href="http://codepad.org/SXfRlJ0w">Rasmus&#8217; instructions</a> for details.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/07/testing-php-5-4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

