<?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>Karl Katzke &#187; zend framework</title>
	<atom:link href="http://www.karlkatzke.com/categories/php/zend-framework/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.karlkatzke.com</link>
	<description>Geek of the Week</description>
	<lastBuildDate>Fri, 16 Dec 2011 19:54:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Zend Framework Debug Bar</title>
		<link>http://www.karlkatzke.com/zend-framework-debug-bar/</link>
		<comments>http://www.karlkatzke.com/zend-framework-debug-bar/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 19:08:16 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=422</guid>
		<description><![CDATA[A replacement for the one thing I missed about Symfony.]]></description>
			<content:encoded><![CDATA[<p><a href="http://jokke.dk/blog/2009/01/introducing_the_scienta_zf_debug_bar">A replacement for the <b>one</b> thing I missed about Symfony.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/zend-framework-debug-bar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Unwritten Manual: Ajax &amp; Flash Multi File Uploader</title>
		<link>http://www.karlkatzke.com/the-unwritten-manual-ajax-flash-multi-file-uploader/</link>
		<comments>http://www.karlkatzke.com/the-unwritten-manual-ajax-flash-multi-file-uploader/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 21:52:34 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=294</guid>
		<description><![CDATA[I think my pet peeve of the day today is going to be developers who think that no documentation or setup instructions should be necessary for their little chunk of code&#8230; especially when it mashes up as many things as Harald Kirschner&#8217;s Fancy Uploader does. (Then again, I should know better than to work off [...]]]></description>
			<content:encoded><![CDATA[<p>I think my pet peeve of the day today is going to be developers who think that no documentation or setup instructions should be necessary for their little chunk of code&#8230; especially when it mashes up as many things as <a href="http://digitarald.de/project/fancyupload/">Harald Kirschner&#8217;s Fancy Uploader</a> does. </p>
<p><small>(Then again, I should know better than to work off of someone&#8217;s code when they term themselves a &#8220;Web Craftsman&#8221; and have personal philosophies as headlining elements of their &#8220;about me&#8221; page.) See also: <a href="http://www.youtube.com/watch?v=zSP8xm_gaK4">New Media Douchebags Explained</a>.)</small></p>
<p>If you&#8217;re banging your head against this like I have been for the past four hours, you&#8217;ve probably figured out a few things. First, the library files that are required to make the javascript work need to be called in a particular order. That order is:</p>
<ol>
<li>The MooTools 1.2 &#8211;FULL&#8211; compressed library. Yes, I know he says you only need a few components. Yes, he lied. Selecting the components he specified will give you an error along the lines of &#8220;window.scroll is not a function at Swiff.Uploader.js (line 62)&#8221; &#8230; so save yourself the time and just pull down the full compressed/mangled MooTools.</li>
<li>Fx.ProgressBar.js</li>
<li>Swiff.Uploader.js</li>
<li>FancyUpload2.js</li>
<li>script.js</li>
</ol>
<p>Stray from that order, and you develop problems. Also, I found that instead of using
<pre>window.addEvent('load',function ...</pre>
<p> as the first line of script.js, it was better to use
<pre>window.addEvent('domready',function ...</pre>
<p>. </p>
<p>Second, let&#8217;s take a look at the sample file that&#8217;s supposed to magically save what we spit out. Specifically, script.php &#8212; which receives the ajax update based on a session variable that&#8217;s set, and then saves the information with an indexed .ini file. First off, it&#8217;s hard to debug. Let&#8217;s use PHP&#8217;s output buffering functions to help that. You can use this snippet of code to write a log of what&#8217;s going on:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"> <span style="color: #cc66cc;">13</span>  <span style="color: #000088;">$logfile</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$folder</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'logfile'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #cc66cc;">14</span>  <span style="color: #990000;">ob_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #cc66cc;">15</span>  <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #cc66cc;">16</span>  <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #cc66cc;">17</span>  <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #cc66cc;">18</span>  <span style="color: #990000;">fwrite</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$logfile</span><span style="color: #339933;">,</span><span style="color: #990000;">ob_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #cc66cc;">19</span>  <span style="color: #990000;">ob_end_clean</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>What you&#8217;ll notice is that, with the default code that comes with the script, you&#8217;ll have the same session ID and since the session ID is created in the javascript and each session ID is incremented in the PHP script, you&#8217;ll overwrite your file if you&#8217;re uploading multiple files &#8212; which was the whole purpose of using flash and AJAX in the first place! This is what we call a brillant(sic) programming decision&#8230; or really, one where the developer just didn&#8217;t really THINK before he wrote it. I&#8217;ve rewritten my function to simply create a directory in the &#8216;uploads&#8217; folder with a batch name that I enter on the main form. After all files have uploaded successfully  (or not), I have a &#8216;continue&#8217; button that does a bunch of database work and sucks the text of the files into the database.</p>
<p>Now, I&#8217;m working with a Zend Framework application here &#8212; this means that I need to make a few changes. First, the script depends on not having any authentication ahead of the request. While the browser will still maintain the session, the ajax requests won&#8217;t have the browser&#8217;s cookies and therefore will bounce off of any preDispatch authentication. To get around this but still stay secure, I generate a (hidden) temporary session ID, store it in the database, and clear the table on a regular basis. </p>
<p>I&#8217;m on a crunched deadline and still don&#8217;t quite have things working yet, but in the next day or two I&#8217;ll post the fruits of my labor. Too bad this uses MooTools and not Dojo&#8230; as far as I know, Dojo still doesn&#8217;t have a flash-compatible uploader that will allow multiple selection. </p>
<p>But back to where I started: <a href="http://digitarald.de/">Harald</a>, dude, you ain&#8217;t no web &#8220;craftsman&#8221; if someone needs to spend 8 hours learning your code and writing workarounds before they can implement it. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/the-unwritten-manual-ajax-flash-multi-file-uploader/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Power of Frameworks</title>
		<link>http://www.karlkatzke.com/the-power-of-frameworks/</link>
		<comments>http://www.karlkatzke.com/the-power-of-frameworks/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 17:59:12 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[zend framework]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[jcarouth]]></category>
		<category><![CDATA[rapid]]></category>
		<category><![CDATA[rapid development]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[unit testing]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=288</guid>
		<description><![CDATA[One of the guys I work with, Jeff Carouth, rolled out an application this week in less than four working days that handles audit trails for a bunch of proposals that our employer&#8217;s executive office needs to track. It&#8217;s bug-free thanks to unit tests, it looks good because our web designer could quickly create a [...]]]></description>
			<content:encoded><![CDATA[<p>One of the guys I work with, <a href="http://carouth.com/">Jeff Carouth</a>, rolled out an application this week in less than four working days that handles audit trails for a bunch of proposals that our employer&#8217;s executive office needs to track. It&#8217;s bug-free thanks to unit tests, it looks good because our web designer could quickly create a layout with Zend_Layout and pages with Zend_View, it gives good feedback thanks to Zend_Form and the Flash Helper, and it does what it&#8217;s needed thanks to Zend_Pdf and many other components of the framework. Way to go, Jeff. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/the-power-of-frameworks/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Zend Framework: Enabling unit testing with MVC</title>
		<link>http://www.karlkatzke.com/zend-framework-enabling-unit-testing-with-mvc/</link>
		<comments>http://www.karlkatzke.com/zend-framework-enabling-unit-testing-with-mvc/#comments</comments>
		<pubDate>Tue, 21 Oct 2008 04:37:57 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[zend framework]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[unit testing]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=284</guid>
		<description><![CDATA[I keep forgetting to post this so I can find it later. The documentation for Zend_Test_PHPUnit requires that you break out your configuration into a plugin as shown in Matthew&#8217;s sample pastebin application.]]></description>
			<content:encoded><![CDATA[<p>I keep forgetting to post this so I can find it later. </p>
<p><a href="http://framework.zend.com/manual/en/zend.test.phpunit.html">The documentation for Zend_Test_PHPUnit</a> requires that you break out your configuration into a plugin as <a href="http://www.karlkatzke.com/zend-framework-dissecting-a-sample-16-app/">shown in Matthew&#8217;s sample pastebin application</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/zend-framework-enabling-unit-testing-with-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework: Profiling Queries with Zend_Db</title>
		<link>http://www.karlkatzke.com/zend-framework-profiling-queries-with-zend_db/</link>
		<comments>http://www.karlkatzke.com/zend-framework-profiling-queries-with-zend_db/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 21:57:49 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[webgrind]]></category>
		<category><![CDATA[xdebug]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend_db]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=282</guid>
		<description><![CDATA[Using an abstraction layer (especially with caching) means that sometimes you don&#8217;t think much about exactly what you&#8217;re doing to the poor database. Here&#8217;s a good article on profiling your database queries and optimizing them. I&#8217;ve found that xdebug + webgrind is also a pretty good solution for when you just need to know how [...]]]></description>
			<content:encoded><![CDATA[<p>Using an abstraction layer (especially with caching) means that sometimes you don&#8217;t think much about exactly what you&#8217;re doing to the poor database. <a href="http://www.techfounder.net/2008/10/12/profiling-queries-with-zend_db-and-optimizing-them-by-hand/">Here&#8217;s a good article on profiling your database queries and optimizing them.</a> I&#8217;ve found that xdebug + webgrind is also a pretty good solution for when you just need to know how many times you&#8217;re nailing the &#8220;query&#8221; button in a script &#8230; sometimes I&#8217;ve been rather surprised. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/zend-framework-profiling-queries-with-zend_db/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework: Dissecting a Sample 1.6 App</title>
		<link>http://www.karlkatzke.com/zend-framework-dissecting-a-sample-16-app/</link>
		<comments>http://www.karlkatzke.com/zend-framework-dissecting-a-sample-16-app/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 18:19:44 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[bootstrap]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[front_controller]]></category>
		<category><![CDATA[initialize]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=268</guid>
		<description><![CDATA[Matthew Weier-O&#8217;Phinney is one of the developers of the Zend Framework, and recently released a pastebin sample application to showcase the new Dojo integration released in 1.6. One of the strengths of the Zend Framework is that there&#8217;s no one way to do anything. Sure, there&#8217;s ways that are set up by default and you [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://weierophinney.net/matthew/">Matthew Weier-O&#8217;Phinney</a> is one of the developers of the Zend Framework, and recently released a <a href="http://weierophinney.net/matthew/archives/189-Pastebin-app-and-conference-updates.html">pastebin sample application</a> to showcase the new Dojo integration released in 1.6. </p>
<p>One of the strengths of the Zend Framework is that there&#8217;s no one way to do anything. Sure, there&#8217;s ways that are set up by default and you can discover these defaults by reading the manuals, but you can get outside of those defaults pretty quickly and easily. For me, one of the hardest things to do is to imagine just how to use the powerful plugin system and excellent collection of extensible that Zend Framework comes with. Matt used both to great effect in this application and I want to learn how and why he made the design decisions he did in order to make my own work better. </p>
<p>I&#8217;m going to take a look at how Matthew did his implementation of the basic structure and some of the details and journal what I learned in the process of dissecting this sample application. </p>
<h2>Front Controller and Bootstrapping</h2>
<p>Let&#8217;s get right down into the nuts and bolts. The good news is that the way Matt does things makes your index controller nice and compact and usable in any context without having to monkey around a lot with configuring the path to your base directory as you move between different development, staging/testing, and production servers. It also enables you to use PHPUnit for unit testing without having to go through any contortions to get the right base libraries in place.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span>
    or <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../application'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$paths</span>     <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'.'</span><span style="color: #339933;">,-</span>
    APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/models'</span><span style="color: #339933;">,</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../library'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">ini_set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'include_path'</span><span style="color: #339933;">,</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span>PATH_SEPARATOR<span style="color: #339933;">,</span> <span style="color: #000088;">$paths</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Loader.php'</span><span style="color: #339933;">;</span>
Zend_Loader<span style="color: #339933;">::</span><span style="color: #004000;">registerAutoload</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">include</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../application/bootstrap.php'</span><span style="color: #339933;">;</span>
&nbsp;
Zend_Controller_Front<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dispatch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The next component you&#8217;re going to have to work on is the bootstrap PHP. There&#8217;s a couple things to point out. First, it re-implements the dirctory application path search. That&#8217;s because the bootstrap (and not the front controller) gets called to load all the libraries when we&#8217;re using PHPUnit for unit testing.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span>
    or <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'development'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BOOTSTRAP'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Loader.php'</span><span style="color: #339933;">;</span>
    Zend_Loader<span style="color: #339933;">::</span><span style="color: #004000;">registerAutoload</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$front</span> <span style="color: #339933;">=</span> Zend_Controller_Front<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$front</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registerPlugin</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> My_Plugin_Initialize<span style="color: #009900;">&#40;</span>APPLICATION_ENV<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #339933;">-&gt;</span><span style="color: #004000;">addControllerDirectory</span><span style="color: #009900;">&#40;</span>APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/controllers'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The last two lines are what we care about from the bootstrap. Remember that Zend_Controller_Front implements the Singleton pattern. Unlike the index.php file, which calls <code>dispatch();</code> against Zend_Controller_Front, the bootstrap adds a plugin and a default controller directory. The plugin&#8217;s where the fascinating stuff happens for the front controller. </p>
<h2>The Controller Plugin</h2>
<p>To set the basic defaults that most sample apps I&#8217;ve seen have all lumped into the front controller or bootstrap, Matthew&#8217;s pastebin application extends a Zend_Controller_Plugin_Abstract into a plugin aptly named &#8216;Initialize&#8217;.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> My_Plugin_Initialize <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Plugin_Abstract</pre></div></div>

<p>The constructor&#8217;s pretty simple. It sets the environment variables including the application path (note that the environment variables assume production settings if another is not already set. Production settings should be the most tightly locked down with no errors or logging shown publicly), makes sure that the Zend Framework loads if it hasn&#8217;t already, and it grabs the Zend_Controller_Front instance and registers the Initialize plugin. </p>
<h2>The Initialize Plugin</h2>
<p>Plugins, in general, are a collection of functions that can be triggered automatically during the lifetime of an object. <a href="http://framework.zend.com/manual/en/zend.controller.plugins.html">You can find out more about Zend_Controller plugins in the framework manual.</a> The important thing about extending Zend_Controller_Plugin_Abstract is the functions that you overload &#8212; routeStartup, routeShutdown, dispatchLoopStartup, preDispatch, postDispatch, and dispatchLoopShutdown. If you don&#8217;t recognize the significance of these places within the controller&#8217;s dispatch loop, stop here and <a href="http://framework.zend.com/manual/en/zend.controller.basics.html">go review the Zend_Controller basics</a>. </p>
<p>Matthew&#8217;s Initialize plugin doesn&#8217;t instantiate all of the database and other objects until he starts up the router. The routeStartup function is overridden as below:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> routeStartup<span style="color: #009900;">&#40;</span>Zend_Controller_Request_Abstract <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>   
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">initControllers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">initLog</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">initCache</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">initDb</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">initView</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Each function is pretty clear on what it does, and you can add steps to each while keeping the freedom, segregation, and modularity intact &#8212; something that was definitely lacking in the way I was building my front controllers. The <code>initControllers()</code> function is a great example &#8212; in this case, it only has one line in it. In a larger, more complex application with an administration section, you could add the controller directories for modules in other folders. </p>
<p>Next time I have the chance to sit down and write, I&#8217;ll take a dive into the dojo stuff. Till then, you can <a href="http://weierophinney.net/matthew/archives/189-Pastebin-app-and-conference-updates.html">download Matthew&#8217;s pastebin app at his site</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/zend-framework-dissecting-a-sample-16-app/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend Framework: If controller not found, use default</title>
		<link>http://www.karlkatzke.com/zend-framework-if-controller-not-found-use-default/</link>
		<comments>http://www.karlkatzke.com/zend-framework-if-controller-not-found-use-default/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 20:21:32 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend controller]]></category>
		<category><![CDATA[zend_controller]]></category>
		<category><![CDATA[zend_router_route]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=254</guid>
		<description><![CDATA[I ran into a big problem with a client site this past week, and I owe it all to my coworker Jeff Carouth for helping me see it from a different angle. My client&#8217;s specification called for two behaviors that monkey with ZF&#8217;s usual domain.tld/module/controller/action or domain.tld/controller/action routing mechanism. They wanted to use a subdomain [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into a big problem with a client site this past week, and I owe it all to my coworker <a href="http://carouth.com/">Jeff Carouth</a> for helping me see it from a different angle. </p>
<p>My client&#8217;s specification called for two behaviors that monkey with ZF&#8217;s usual domain.tld/module/controller/action or domain.tld/controller/action routing mechanism. They wanted to use a subdomain to load the client&#8217;s customer-customized skin (i.e. customer1.domain.tld, customer2.domain.tld) &#8212; no problem. The issue arose when they also wanted to have domain.tld/customer1 and domain.tld/customer2 work the same as the subdomain. Obviously, customer1 and customer2 are not going to resolve to valid controllers, which results in an exception being thrown and the error page being displayed unless a valid static route is found&#8230;</p>
<p>Jeff made a huge contribution by looking at the problem at a much lower level. I was considering using the routing mechanism to accomplish this by adding a whole bunch of static routes ahead of the default router. But with an install that&#8217;s supposed to support hundreds of my clients&#8217; customers, it&#8217;s not exactly practical to load that list for every single request! Instead, the customer name being passed in as a controller <i>is indeed an exception</i>, and should be handled as such!</p>
<p>To make this work, the first thing that needs to change is that Zend_Controller_Front needs to throw exceptions instead of passing them to the error controller. You can do this by using</p>
<pre>
$front = Zend_Controller_Front::getInstance();
$front->throwExceptions(true);
</pre>
<p>The following feels to me like a code stink, but for all intents and purposes is a valid coding practice when handling exceptions. We&#8217;re basically going to tell the front controller to &#8220;run the front controller once with the default routing rules, and if it breaks, run again with a custom routing rule.&#8221; </p>
<pre>
try {
  $front->run(BASE.'app/controllers');
} catch  (Zend_Controller_Dispatcher_Exception $e) {
  $myRoute = new Zend_Controller_Router_Route(
      '/:customer/:action/*',
      array(
         'controller' => 'index'
         ,'action' => 'index'));
}
  $router->addRoute('default',$myRoute);
  $front->setRouter($router);
  $front->throwExceptions(false);
  $front->run(BASE.'app/controllers');
}
</pre>
<p>I don&#8217;t think you actually need that <code>$front->setRouter()</code> call in there, but it&#8217;s not hurting anything &#8230; Do note the call to restore the default behavior of Zend_Front_Controller::throwExceptions() back to false. That&#8217;s important or your error module won&#8217;t have exceptions routed to it correctly. </p>
<p>Thanks, Jeff! Owe you a beer for that one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/zend-framework-if-controller-not-found-use-default/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend Framework Architecture @ PHP::Impact</title>
		<link>http://www.karlkatzke.com/zend-framework-architecture-phpimpact/</link>
		<comments>http://www.karlkatzke.com/zend-framework-architecture-phpimpact/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 12:18:42 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[php 5.3]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=201</guid>
		<description><![CDATA[Zend Framework Architecture &#8212; A promising article in one of the better PHP blogs. Doesn&#8217;t take into account the work that Matthew Weier-O&#8217;Phinney has already done to start refactoring ZF for 5.3.]]></description>
			<content:encoded><![CDATA[<p><a href="http://phpimpact.wordpress.com/2008/07/28/zend-framework-architecture/">Zend Framework Architecture</a> &#8212; A promising article in one of the better PHP blogs. Doesn&#8217;t take into account the work that Matthew Weier-O&#8217;Phinney <a href="http://weierophinney.net/matthew/archives/181-Migrating-OOP-Libraries-and-Frameworks-to-PHP-5.3.html">has already done to start refactoring ZF for 5.3</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/zend-framework-architecture-phpimpact/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reading List; 15July08</title>
		<link>http://www.karlkatzke.com/reading-list-15july08/</link>
		<comments>http://www.karlkatzke.com/reading-list-15july08/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 01:51:51 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[reading list]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[icons]]></category>
		<category><![CDATA[rfid]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend_controller]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=175</guid>
		<description><![CDATA[RFID industry tries to spin toll findings. Think your toll tags are secure devices? Think again. This really concerns me because we&#8217;re now using the same technology as toll tags for our garage entrance at TAMU. Beautiful icons by Felix Sockwell for the iPhone&#8217;s NY Times application. Improving the Performance of Zend Controller]]></description>
			<content:encoded><![CDATA[<ul>
<li><a href="http://rdist.root.org/2008/07/14/rfid-industry-tries-to-spin-toll-findings/">RFID industry tries to spin toll findings</a>. Think your toll tags are secure devices? Think again. This really concerns me because we&#8217;re now using the same technology as toll tags for our garage entrance at TAMU.</li>
<li><a href="http://www.drawger.com/felixsockwell/?section=comments&#038;article_id=5804">Beautiful icons by Felix Sockwell for the iPhone&#8217;s NY Times application.</a></li>
<li><a href="http://phpimpact.wordpress.com/2008/07/15/improving-the-performance-of-zend_controller/">Improving the Performance of Zend Controller</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/reading-list-15july08/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Well, maybe.</title>
		<link>http://www.karlkatzke.com/well-maybe/</link>
		<comments>http://www.karlkatzke.com/well-maybe/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 12:10:14 +0000</pubDate>
		<dc:creator>karlkatzke</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[punditry]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[zend_framework]]></category>

		<guid isPermaLink="false">http://www.karlkatzke.com/?p=171</guid>
		<description><![CDATA[First, read this: The Answer is No @ The Big Contrarian. In response: At least part of the problem is that we STILL haven&#8217;t defined the question. Is it that we develop a web application to solve problems in the most efficient and graceful way? Or is it that we develop a web application in [...]]]></description>
			<content:encoded><![CDATA[<p>First, read this: <a href="http://www.bigcontrarian.com/2008/07/11/the-answer-is-no/">The Answer is No @ The Big Contrarian</a>. </p>
<p>In response: At least part of the problem is that we STILL haven&#8217;t defined the question. Is it that we develop a web application to solve problems in the most <i>efficient</i> and <i>graceful</i> way? Or is it that we develop a web application in the most <i>maintainable</i> and <i>understandable</i> way?</p>
<p>To extend Jack&#8217;s metaphor of hammers and nails, the former would involve using a different hammer every time we need to drive a hammer into different wood. But you could quickly build up an environment where you had many different nails driven into boards at different depths and angles due to the blows of so many hammers. If you&#8217;ve driven the nail too deep for the wood, you may not be able to get it out at some point in the future without destroying the wood completely &#8212; aka one of those oft-talked-about failed development projects. </p>
<p>The discussion of how to develop web applications and what technology to use isn&#8217;t just a <b>computer science</b> decision, it&#8217;s a <b>business decision</b>. As someone who approaches computer problems from a utility and maintainability perspective, I want three things from a development tool. First, I want it to set (but not force) a style so that all programmers can code in a similar fashion, and programmers who are new to the project can walk in and get a feel for things within a few minutes. Second, I want it to be maintained and maintainable into the future as the language and development methods change. Third, I want it to be based on a stable technology that scales well. These are all utility things, considered at a much more abstract level than the computer science problems that Jack talks about. </p>
<p>If programmers didn&#8217;t search for new tools, the web would still look like it did in 1995, and we&#8217;d all still be developing CGI applications in C. Be thankful that the world moves on and that there are people and companies willing to develop and pursue new ways of doing things. The dogmatic approach some developers take towards their favorite technology isn&#8217;t bad, per say. It&#8217;s just part of the darwinian selection of the platforms and technologies that will move on. And in some cases, the programmers who won&#8217;t, ground beneath the ceaseless ever-rolling wheels of progress. </p>
<p>It&#8217;s fine to allow people to search for new tools and to be evangelists of their favorite tools and processes. <b>On their own time.</b> When they come to work at a job (be it consulting or other), someone needs to be laying down guidelines of how to do a project, and someone needs to enforce that all projects within one cone of perception use the same technologies, or use technologies that will be compatible in the future. </p>
<p><i>Standardization is the only way to maintain a high level of support</i>. Corporate development jobs regularly fail because someone had to do it their way. (I&#8217;m guilty of this too, but I&#8217;ve learned my lesson.) It&#8217;s the responsibility of the lead programmers to make sure that this doesn&#8217;t happen. Even if Zend Framework or Symfony or Ruby on Rails or some other technology is the most elegant and fastest way to solve a problem, don&#8217;t do it unless that&#8217;s what your group has standardized on, supports, and knows. If you&#8217;re a PHP shop, don&#8217;t write a webapp in Python. If you&#8217;re a MySQL shop, don&#8217;t use Postgres for this one project to &#8220;try it out.&#8221; Don&#8217;t. Just don&#8217;t. Pick one thing that&#8217;s good at many areas and just use it. </p>
<p>That isn&#8217;t to say that you shouldn&#8217;t improve your chosen one. <a href="http://phpdoctrine.org">Doctrine</a> exists because some developers wanted an ActiveRecord implementation in PHP that was as easy to use as Rails&#8217; is. So they wrote one. Symfony came from nearly the same place. Zend Framework&#8217;s rapidly arriving ajax integration is a direct outgrowth of what Symfony did with theirs. Just keep in mind that it&#8217;s not features from the programmer&#8217;s point of view that matter, it&#8217;s features from the point of view of the downstream developers that will support the application in the future and the systems administrators who have to maintain the platform that you&#8217;re on. If you keep it simple and just pick one for your particular shop, they can keep it simple too. And simple means stable. Stable, maintainable, and understandable means happy users, and are considered features by your users. </p>
<p>Make sure you deliver those features, or your project too <i>will</i> fail. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkatzke.com/well-maybe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

