<?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; Zend Framework</title>
	<atom:link href="http://bradley-holt.com/tag/zend-framework/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 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>Speaking at SXSW Interactive 2011</title>
		<link>http://bradley-holt.com/2011/01/speaking-at-sxsw-interactive-2011/</link>
		<comments>http://bradley-holt.com/2011/01/speaking-at-sxsw-interactive-2011/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 00:27:11 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[DC PHP]]></category>
		<category><![CDATA[New York PHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SXSW]]></category>
		<category><![CDATA[SXSWi]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=950</guid>
		<description><![CDATA[I will be speaking at SXSW Interactive 2011. My talk will be a solo presentation on Zend Framework 2.0 and PHP 5.3 Web Applications. A big thanks to everyone who voted for my talk in the panel picker! I&#8217;ll be giving a preview of this talk at DC PHP on February 9th and at New [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://sxsw.com/interactive/talks"><img class="alignright" style="border: 0pt none;" src="http://img.sxsw.com/2011/logos/I_SeeMe.png" border="0" alt="See Me Speak at SXSW Interactive 2011" width="223" height="94" /></a> <a href="http://sxsw.com/interactive/talks">I will be speaking at SXSW Interactive 2011</a>. My talk will be a solo presentation on <a href="http://panelpicker.sxsw.com/ideas/view/6336">Zend Framework 2.0 and PHP 5.3 Web Applications</a>. A big thanks to everyone who voted for my talk in the panel picker! I&#8217;ll be giving a preview of this talk at <a href="http://www.meetup.com/DC-PHP/calendar/15047736/">DC PHP on February 9th</a> and at <a href="http://www.nyphp.org/PHP-Presentations/178_Zend-Framework-20-PHP-53-Web-Applications">New York PHP on February 22nd</a>. If you have specific questions you&#8217;d like to see addressed then <a href="http://goo.gl/mod/cBJN">please let me know</a>!</p>
<p><em>Update (2/9/2011)</em>: I will no longer be giving this presentation. Instead, SXSW has invited me to curate a Workshop on <a href="http://schedule.sxsw.com/events/event_IAP6336">Big Data and APIs for PHP Developers</a>. While I would have really enjoyed giving my Zend Framework talk, this new Workshop is shaping up to be an excellent session. The Workshop&#8217;s speakers will be <a href="http://www.laurathomson.com/">Laura Thomson</a>, <a href="http://eliw.com/">Eli White</a>, <a href="http://twitter.com/jsteeleeditor">Julie Steele</a>, <a href="http://twitter.com/sinned">Dennis Yang</a>, and <a href="http://twitter.com/dzuelke">David Zülke</a>. I&#8217;ll update my blog with more details later.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/01/speaking-at-sxsw-interactive-2011/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Behind The New VPR Homepage</title>
		<link>http://bradley-holt.com/2010/10/behind-the-new-vpr-homepage/</link>
		<comments>http://bradley-holt.com/2010/10/behind-the-new-vpr-homepage/#comments</comments>
		<pubDate>Mon, 11 Oct 2010 15:09:47 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Atom Syndication Format]]></category>
		<category><![CDATA[ClearBearing]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[FOSS]]></category>
		<category><![CDATA[Found Line]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Mobile Computing]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[Open Standards]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Public Media]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Vermont]]></category>
		<category><![CDATA[VPR]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=888</guid>
		<description><![CDATA[Found Line had the privilege of designing and developing Vermont Public Radio&#8216;s (VPR) new homepage. VPR&#8217;s Online Manager, Jonathan Butler, wrote a blog post about how the redesigned homepage delivers more content to VPR.net visitors. Here I&#8217;ll talk about the technology behind this new homepage. Atom Syndication Format Most of VPR&#8217;s web content is currently [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://foundline.com/">Found Line</a> had the privilege of designing and developing <a href="http://www.vpr.net/">Vermont Public Radio</a>&#8216;s (VPR) new homepage. VPR&#8217;s Online Manager, Jonathan Butler, wrote a blog post about how the <a href="http://vprblog.blogspot.com/2010/10/new-vprnet-homepage.html">redesigned homepage delivers more content to VPR.net visitors.</a> Here I&#8217;ll talk about the technology behind this new homepage.</p>
<h3>Atom Syndication Format</h3>
<p>Most of VPR&#8217;s web content is currently stored in a proprietary content management system (CMS). The first step was publishing the needed content from the CMS out into an open format. VPR&#8217;s Dan Allen published from the CMS <a href="http://www.atomenabled.org/">Atom</a> feeds of the various content we would need for the new homepage.</p>
<h3>PHP and Zend Framework</h3>
<p>Once we had the needed Atom feeds, we created a <a href="http://framework.zend.com/">Zend Framework</a> web application to import these feeds. Components such as <a href="http://framework.zend.com/manual/en/zend.feed.reader.html">Zend_Feed_Reader</a> made the job easier. The weather data comes from the National Oceanic and Atmospheric Administration&#8217;s (NOAA) National Weather Service&#8217;s <a href="http://www.weather.gov/forecasts/xml/rest.php">National Digital Forecast Database XML/REST Service</a>. The market data comes from the <a href="http://code.google.com/apis/finance/">Google Finance API</a>.</p>
<h3>CouchDB</h3>
<p>All of the data (except for weather, which is pulled directly with a bit of caching) is stored in <a href="http://couchdb.apache.org/">CouchDB</a>. Since we&#8217;re storing documents with varying metadata (i.e. Atom entries) choosing a document-oriented database made a lot of sense. CouchDB&#8217;s map/reduce views make for very efficient queries. Its RESTful HTTP API provides a lot of options for scaling and caching. We&#8217;re caching documents within the Zend Framework application and conditionally requesting these documents from CouchDB with ETags when a cache is available. The current cache is simply file-based but we&#8217;re considering using <a href="http://memcached.org/">Memcached</a> for even better performance. On a related note, the homepage itself also supports conditional HTTP requests.</p>
<h3>Apache and nginx</h3>
<p>We had the pleasure of working with another great Vermont company, <a href="http://www.clearbearing.com/">ClearBearing</a>, on this project. ClearBearing handles the infrastructure layer for <a href="http://www.vpr.net/">VPR.net</a>. The current website was (and still is) served up by <a href="http://httpd.apache.org/">Apache</a>. ClearBearing already had <a href="http://nginx.org/">nginx</a> in place as a reverse proxy to handle caching. Since we weren&#8217;t replacing the entire CMS we needed a way for the existing CMS and this new application to coexist. We decided to host the new application separately (still administered by ClearBearing) and reverse proxy requests for certain URIs (primarily the homepage) to the new application. This provides a clean separation between the new application and the existing CMS while still allowing for them to be hosted on the same domain from an end-user perspective.</p>
<h3>Licensing</h3>
<p>You&#8217;ll notice that all of the standards used are open standards and all of the technologies used are free and open source software. Additionally, all of the code we have written for VPR is licensed to them under the permissive <a href="http://www.opensource.org/licenses/bsd-license.php">New BSD License</a>. This means that VPR is free to use this code however they want, study and modify the code, and redistribute the code as-is or modified. They can do all of this without paying additional licensing fees.</p>
<h3>Design</h3>
<p>While this post is primarily about the technology behind VPR&#8217;s new homepage, I should mention that Found Line&#8217;s <a href="http://foundline.com/people/jason-pelletier">Jason Pelletier</a> designed the new homepage and implemented all of its HTML and CSS. We worked closely with Jonathan Butler and John Van Hoesen, Vice President for News &amp; Programming, to make sure the new design meets the needs of website visitors and the organization.</p>
<h3>Next Steps</h3>
<p>The launch of this new homepage was just one iteration with many more to come. As Jonathan Butler mentioned in his blog post, VPR has plans to further improve online services for their listeners. Look for a redesigned VPR Classical page soon. There are also plans for better mobile access to VPR and VPR Classical programming. Fortunately much of the work that has been done can be leveraged to create additional online services for VPR&#8217;s listeners.</p>
<p>A special thanks for the <a href="http://www.vpr.net/support/">support of VPR&#8217;s listeners</a>—you made this new homepage possible! If you have questions, comments, complaints, or suggestions about the new homepage then please <a href="http://www.vpr.net/inside_vpr/contact_us/?subject=VPR+Homepage">contact VPR</a> directly with your feedback (although you&#8217;re welcome to comment here as well).</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/10/behind-the-new-vpr-homepage/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Zend Framework 2.0 and PHP 5.3 Web Applications SXSW Interactive Panel</title>
		<link>http://bradley-holt.com/2010/08/zend-framework-2-0-and-php-5-3-web-applications-sxsw-interactive-panel/</link>
		<comments>http://bradley-holt.com/2010/08/zend-framework-2-0-and-php-5-3-web-applications-sxsw-interactive-panel/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 17:01:13 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SXSW]]></category>
		<category><![CDATA[SXSWi]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=751</guid>
		<description><![CDATA[I have submitted a panel on Zend Framework 2.0 and PHP 5.3 Web Applications for the 2011 SXSW Interactive Festival. Please consider giving this panel your vote. From the panel&#8217;s description: Zend Framework is a free/open source web application framework. It can be used either as a component library or as a full-stack Model–View–Controller (MVC) [...]]]></description>
			<content:encoded><![CDATA[<p>I have submitted a panel on <a href="http://panelpicker.sxsw.com/ideas/view/6336">Zend Framework 2.0 and PHP 5.3 Web Applications</a> for the 2011 <a href="http://sxsw.com/interactive">SXSW Interactive Festival</a>. Please consider giving this panel your vote. From the panel&#8217;s description:</p>
<blockquote><p>Zend Framework is a free/open source web application framework. It can  be used either as a component library or as a full-stack  Model–View–Controller (MVC) framework. As compared to its 1.x  counterparts, Zend Framework 2.0 is easier to learn, trivially simple to  extend, and more performant. It is also easier to use just specific  parts of the framework as needed. We will explore the many features of  Zend Framework 2.0 including its tooling, functional testing, form,  database, pagination, date, markup, navigation, and MVC components.   Zend Framework 2.0 takes advantages of several new features in PHP 5.3  including closures/lambdas, namespaces, and late static binding. We will  explore some of these new features to understand why PHP 5.3 is a  requirement for Zend Framework 2.0 and how you can leverage these new  features within your application itself. An example web application will  be provided that you can use as a reference when building your own Zend  Framework web application.</p></blockquote>
<p>For those wondering, Zend Framework 2.0 is not out yet but SXSW is not until next March and Zend Framework 2.0 will most likely be released by then. The description above is based on the <a href="http://framework.zend.com/wiki/display/ZFDEV2/Zend+Framework+2.0+Requirements">Zend Framework 2.0 Requirements</a> and discussions on the Zend Framework contributors mailing list.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/08/zend-framework-2-0-and-php-5-3-web-applications-sxsw-interactive-panel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Magento Roundtable</title>
		<link>http://bradley-holt.com/2010/05/magento-roundtable/</link>
		<comments>http://bradley-holt.com/2010/05/magento-roundtable/#comments</comments>
		<pubDate>Thu, 27 May 2010 15:20:27 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[BTV]]></category>
		<category><![CDATA[btvphpug]]></category>
		<category><![CDATA[eCommerce]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Vermont]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=691</guid>
		<description><![CDATA[Next week&#8217;s Burlington, VT PHP Users Group meeting will be a Magento Roundtable discussion. From the meeting description: Over the last year, Magento has increased in popularity as a viable open source eCommerce platform for the mid to large scale online retailer. This rapid growth has lead to many questions on what has been fixed, what [...]]]></description>
			<content:encoded><![CDATA[<p>Next week&#8217;s <a href="http://groups.google.com/group/burlington-vt-php">Burlington, VT PHP Users Group</a> meeting will be a <a href="http://btvphpug-2010-06-03.eventbrite.com/">Magento Roundtable</a> discussion. From the meeting description:</p>
<blockquote><p>Over the last year, <a href="http://www.magentocommerce.com/" target="_blank">Magento</a> has  increased in popularity as a viable open source eCommerce platform for  the mid to large scale online retailer. This rapid growth has lead to  many questions on what has been fixed, what continues to be a problem,  and how complex a system an eCommerce engine needs to be.</p>
<p>Have you used Magento? Are you considering using it for an upcoming  project? Do you have a specific problem that Magento solves for you and  would like to share your story? Join the roundtable and compare notes  with others who have experience with Magento.</p>
<p>Meetings are open to  the public via RSVP. You will have the chance to network and connect  with fellow PHP developers.</p>
<p>To Participate:</p>
<ol>
<li>Register on Eventbrite.</li>
<li>Sign up for the <a href="http://groups.google.com/group/burlington-vt-php">Burlington, VT  PHP User Group</a> list on Google Groups.</li>
<li>Forward this <a href="http://btvphpug-2010-06-03.eventbrite.com/">link</a> to anyone else you feel would be interested in this meeting&#8217;s topics.</li>
</ol>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/05/magento-roundtable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TEK·X Day Two</title>
		<link>http://bradley-holt.com/2010/05/tek%c2%b7x-day-two/</link>
		<comments>http://bradley-holt.com/2010/05/tek%c2%b7x-day-two/#comments</comments>
		<pubDate>Fri, 21 May 2010 04:50:26 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHPUnit]]></category>
		<category><![CDATA[Software Deployment]]></category>
		<category><![CDATA[SPL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[tekX]]></category>
		<category><![CDATA[tekX10]]></category>
		<category><![CDATA[Xdebug]]></category>
		<category><![CDATA[XMPP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=683</guid>
		<description><![CDATA[It&#8217;s hard to believe tomorrow is the last day of TEK·X. Where did the time go? Today started with Matthew Schmidt&#8217;s 10 Developer Trends in 2010. He talked about agile development, browser standards, AJAX, security vulnerabilities, RIAs, touch interfaces, key/value stores, version control, cloud computing, and dynamic languages. While not a bad keynote, the topics [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s hard to believe tomorrow is the last day of <a href="http://tek.phparch.com/">TEK·X</a>. Where did the time go? Today started with Matthew Schmidt&#8217;s 10 Developer Trends in 2010. He talked about agile development, browser standards, AJAX, security vulnerabilities, RIAs, touch interfaces, key/value stores, version control, cloud computing, and dynamic languages. While not a bad keynote, the topics seemed fairly basic and obvious given the audience.</p>
<p>Next up for me was Derick Rethans&#8217; <a href="http://xdebug.org/">Xdebug</a> talk. Xdebug is an extremely useful tool for PHP developers. I&#8217;ve used its <a href="http://xdebug.org/docs/stack_trace">stack trace</a> feature as well as its <a href="http://www.phpunit.de/manual/3.4/en/code-coverage-analysis.html">code coverage analysis via PHPUnit</a>. I&#8217;ve also dabbled with its <a href="http://xdebug.org/docs/profiler">profiling</a> capabilities. The session introduced me to several other Xdebug features with which I&#8217;d like to experiment.</p>
<p>After that I had the pleasure of seeing Matthew Turland&#8217;s talk on <a href="http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/">New SPL Features in PHP 5.3</a>. New SPL data structures in PHP 5.3 include stacks, queues, heaps, priority queues, and sets. Matthew provided test code that compared the performance and memory usage of each these new data structures to that of using PHP&#8217;s array functionality.</p>
<p>I skipped the first afternoon session to take part in the Hack Track which happened to coincide with Zend Framework&#8217;s <a href="http://devzone.zend.com/article/12150">May Bug Hunt Days</a>. I was granted commit access and directly committed my first bug fix, a small change to <a href="http://framework.zend.com/issues/browse/ZF-9845">make HTTP headers case-insensitive</a>.</p>
<p>Others stuck around to fix more bugs while I went to check out Bill Karwin&#8217;s <a href="http://www.slideshare.net/billkarwin/models-for-hierarchical-data">Models for Hierarchical Data with SQL and PHP</a>. Examples of hierarchical data include categories/subcategories, bill of materials, and threaded discussions. Bill talked about four main approaches to storing hierarchical data in SQL databases: adjacency list, path enumeration, nested sets, and usage of a closure table.</p>
<p>The <em>adjacency list</em> is a naive approach that almost everyone tries first. Basically, each entry knows its immediate parent. The problem with this approach is that querying deep trees can be very inefficient involving many joins. <em>Path enumeration</em> involves storing an enumerated chain of ancestors in each entry. This can be very efficient and take advantage of indexing. However, there is no referential integrity with this approach. The <em>nested set</em> approach seemed a bit complicated. I don&#8217;t feel I can explain it properly here, so you&#8217;ll have to check out Bill&#8217;s slides if you&#8217;re interested in how this works. The <em>closure table</em> approach made the most sense to me and didn&#8217;t seem overly complicated. Not only do you store each entry, but you also store every path including those from the parent node to each descendant, those from each ancestor to its child node, as well as a reflexive reference from the node to itself.</p>
<p>My final session of the day was Travis Swicegood&#8217;s Building Real-Time Applications with XMPP, the <a href="http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol">Extensible Messaging and Presence Protocol</a>. If you&#8217;ve use Google Talk then you&#8217;ve used XMPP. As a web developer, the request and response pattern in HTTP is ingrained into my thinking. However, XMPP is a very different creature in that it keeps a socket open during what can be a lengthy exchange of messages. While I don&#8217;t think HTTP is going away anytime soon, real-time applications involving potentially large numbers of publishers and subscribers (e.g. Twitter) are becoming more prevalent and XMPP is well suited for this environment.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/05/tek%c2%b7x-day-two/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Searching A Field With Digits In Zend Framework&#8217;s Lucene Component</title>
		<link>http://bradley-holt.com/2010/04/searching-a-field-with-digits-in-zend-frameworks-lucene-component/</link>
		<comments>http://bradley-holt.com/2010/04/searching-a-field-with-digits-in-zend-frameworks-lucene-component/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 21:42:34 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Lucene]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=662</guid>
		<description><![CDATA[Recently I ran into a bug in one of our applications using Zend_Search_Lucene where the same document was showing up multiple times in search results. Actually, many different documents were showing up more than once. I tracked it down to the routine that updated indexed documents. With Zend_Search_Lucene you can&#8217;t actually update indexed documents, but [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I ran into a bug in one of our applications using <a href="http://framework.zend.com/manual/en/zend.search.lucene.html">Zend_Search_Lucene</a> where the same document was showing up multiple times in search results. Actually, many different documents were showing up more than once. I tracked it down to the routine that updated indexed documents. With Zend_Search_Lucene you can&#8217;t actually update indexed documents, but you can delete an indexed document and then insert a new, updated, document. In order to delete a document you first must search for it by a previously indexed field and then, once found, delete it using its internal document identifier. The problem seemed to be that documents were not being found and deleted when updated, thus duplicates of the same document were accumulating on each update.</p>
<p>The field I was indexing, and subsequently using to find and delete documents, was a 40 character SHA-1 hash. While trying to track down the bug in my application, I discovered that only documents having a SHA-1 hash beginning with a digit were getting duplicated (in other words, were <em>not</em> being found when I tried to delete them) and that documents having a SHA-1 beginning with a letter were not getting duplicated (in other words, <em>were</em> being found and deleted).</p>
<p>A Stack Overflow post on <a href="http://stackoverflow.com/questions/547180/searching-numbers-with-zend-search-lucene">searching numbers with Zend_Search_Lucene</a> had the information I needed to fix the bug. First, I changed the hash field from a text field to a keyword field which prevented it from being tokenized (this, of course, required me to delete the existing index and re-index every document). Second, when searching on the hash field I replaced the default Text analyzer with the TextNum analyzer. These two changes seemed to do the trick, as I haven&#8217;t seen any duplicate search results after having run several index updates.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/04/searching-a-field-with-digits-in-zend-frameworks-lucene-component/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Layouts in Zend Framework</title>
		<link>http://bradley-holt.com/2010/03/layouts-in-zend-framework/</link>
		<comments>http://bradley-holt.com/2010/03/layouts-in-zend-framework/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 18:49:19 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=634</guid>
		<description><![CDATA[In my previous post in this series we looked at Zend Framework’s routing and Model-View-Controller (MVC) components. In this post we&#8217;ll take slight detour and explore Zend_Layout, a component that lets you have a consistent template for the layout of pages throughout your website. In the past you may have implemented consisted layouts in PHP [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://bradley-holt.com/2010/02/mvc-in-zend-framework/">previous post</a> in this series we looked at Zend Framework’s routing and <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller</a> (MVC) components. In this post we&#8217;ll take slight detour and explore <a href="http://framework.zend.com/manual/en/zend.layout.html"><code>Zend_Layout</code></a>, a component that lets you have a consistent template for the layout of pages throughout your website.</p>
<p>In the past you may have implemented consisted layouts in PHP using &#8220;includes&#8221; but, as you&#8217;ll see, layouts are much easier to manage than &#8220;includes&#8221;. The primary improvement over &#8220;includes&#8221; is that you can change the entire layout of your website without editing every single PHP script. This is because the layout decides where the content gets placed instead of each PHP script including the needed partials (e.g. header and footer). This is accomplished through an implementation of the <a href="http://martinfowler.com/eaaCatalog/twoStepView.html">Two Step View</a> pattern.</p>
<p>If you&#8217;re using <a href="http://framework.zend.com/manual/en/zend.tool.html"><code>Zend_Tool</code></a> then you can enable layouts using the command <code>zf enable layout</code>. This will create a layout view script, <a href="http://github.com/bradley-holt/postr/blob/master/application/layouts/scripts/layout.phtml"><code>application/layouts/scripts/layout.phtml</code></a>, and add the following line to the <code>production</code> section of your <a href="http://github.com/bradley-holt/postr/blob/master/application/configs/application.ini"><code>application/configs/application.ini</code></a> file:</p>
<pre><code>resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"</code></pre>
<p><code>Zend_Layout</code> has a <a href="http://framework.zend.com/manual/en/zend.controller.plugins.html">front controller plugin</a> that has two main jobs. First, it takes care of rendering the layout for us. Second, it retrieves what are called &#8220;named segments&#8221; from Zend Framework&#8217;s response object and assigns them as variables in your layout. A segment named &#8220;default&#8221; is assigned to the variable named <code>content</code>. Typically (unless you do something to override this) the &#8220;default&#8221; segment will contain the output of your individual controller actions. This means that you can render the content of your controller actions wherever you&#8217;d like in your layout view script by outputting the value of <code>$this-&gt;layout()-&gt;content</code>.</p>
<p>In the demo blogging application, <a href="http://github.com/bradley-holt/postr">Postr</a>, I&#8217;ve also created a header layout view script, <a href="http://github.com/bradley-holt/postr/blob/master/application/layouts/scripts/header.phtml"><code>application/layouts/scripts/header.phtml</code></a>, and a footer layout view script, <a href="http://github.com/bradley-holt/postr/blob/master/application/layouts/scripts/footer.phtml"><code>application/layouts/scripts/footer.phtml</code></a>. The header and footer layout view scripts are rendered by outputting the results of <code>$this-&gt;render('header.phtml')</code> and <code>$this-&gt;render('footer.phtml')</code>, respectively.</p>
<p>In my next post in this series I plan on taking a look at the <code>Entry</code> controller (<a href="http://github.com/bradley-holt/postr/blob/master/application/controllers/EntryController.php"><code>application/controllers/EntryController.php</code></a>) in the demo blogging application, <a href="http://github.com/bradley-holt/postr">Postr</a>. We&#8217;ll explore its actions and corresponding view scripts. <a href="http://framework.zend.com/manual/en/zend.form.html"><code>Zend_Form</code></a>, <a href="http://framework.zend.com/manual/en/zend.paginator.html"><code>Zend_Paginator</code></a>, and modeling domain objects will be touched on briefly, but explored in more depth in later posts.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/03/layouts-in-zend-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MVC in Zend Framework</title>
		<link>http://bradley-holt.com/2010/02/mvc-in-zend-framework/</link>
		<comments>http://bradley-holt.com/2010/02/mvc-in-zend-framework/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 17:51:37 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=573</guid>
		<description><![CDATA[In my previous post in this series we looked at how Zend Framework applications can be bootstrapped. We saw the configuration file (application/configs/application.ini) and the Bootstrap class (in application/Bootstrap.php) from a demo blogging application, Postr. What happens once your application is bootstrapped and run? That&#8217;s where Zend Framework&#8217;s routing and Model-View-Controller (MVC) components come in [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://bradley-holt.com/2010/01/bootstrapping-zend-framework-applications/">previous post</a> in this series we looked at how Zend Framework applications can be bootstrapped. We saw the configuration file (<a href="http://github.com/bradley-holt/postr/blob/master/application/configs/application.ini"><code>application/configs/application.ini</code></a>) and the <code>Bootstrap</code> class (in <a href="http://github.com/bradley-holt/postr/blob/master/application/Bootstrap.php"><code>application/Bootstrap.php</code></a>) from a demo blogging application, <a href="http://github.com/bradley-holt/postr">Postr</a>. What happens once your application is bootstrapped and run? That&#8217;s where Zend Framework&#8217;s routing and <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller</a> (MVC) components come in (technically there are a few steps in-between, but we&#8217;ll come back to that in a future post).</p>
<dl>
<dt>Model</dt>
<dd>Your domain objects. There is no <code>Zend_Model</code> since your domain logic is specific to your application. However, there are some best practices that have emerged in the Zend Framework community including <a href="http://martinfowler.com/eaaCatalog/dataMapper.html">Data Mappers</a> (which I&#8217;ll talk about later).</dd>
<dd> See example Models in <a href="http://github.com/bradley-holt/postr/tree/master/application/models/"><code>application/models/</code></a></dd>
<dt>View</dt>
<dd>The presentation layer. The default implementation uses PHP templates called <em>view scripts</em>. View script files have a default suffix of <code>.phtml</code>. There should be no domain logic in your view scripts. By default, there is one view script per controller action (we&#8217;ll see what that means shortly).</dd>
<dd>See example Views in <a href="http://github.com/bradley-holt/postr/tree/master/application/views/"><code>application/views/</code></a></dd>
<dt>Controller</dt>
<dd>Connects the Model and the View. Each Controller contains one or more <em>actions</em>. The Controller&#8217;s job is to interpret input and pass it to the Model and also to provide Model data to the View.</dd>
<dd>See example Controllers in <a href="http://github.com/bradley-holt/postr/tree/master/application/controllers/"><code>application/controllers/</code></a></dd>
</dl>
<p>By default, Zend Framework will route requests based on URI segments as follows:</p>
<pre><code>:controller/:action[/:key/:value]</code></pre>
<p>A few example URIs:</p>
<ul>
<li><code>foo/bar</code> (foo controller, bar action)</li>
<li><code>foo/bar/baz/shaz</code> (foo controller, bar action, baz=shaz)</li>
</ul>
<p>It is possible to customize this routing in pretty much any way conceivable but I&#8217;d suggest sticking with the default routing until you have a good handle on how it works.</p>
<p>In my <a href="http://bradley-holt.com/2010/03/layouts-in-zend-framework/">next post</a> in this series I plan on taking a slight detour so that we can explore a very useful component, <code><a href="http://framework.zend.com/manual/en/zend.layout.html">Zend_Layout</a></code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/02/mvc-in-zend-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

