<?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>Devlog &#187; Design Patterns</title>
	<atom:link href="http://devlog.info/cat/design-patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://devlog.info</link>
	<description>One developers blog.</description>
	<lastBuildDate>Tue, 31 Aug 2010 18:45:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cross-domain AJAX with JSONP</title>
		<link>http://devlog.info/2010/03/10/cross-domain-ajax/</link>
		<comments>http://devlog.info/2010/03/10/cross-domain-ajax/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 23:42:54 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[cross-domain]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[jsonp]]></category>

		<guid isPermaLink="false">http://devlog.info/?p=139</guid>
		<description><![CDATA[Anyone who develops Javascript long enough undoubtedly runs into difficulties involving the various security features all browser vendors implement. These security features are a good thing -- they protect us from malicious users hijacking our browsing experience. But they can certainly cause some headaches. The security feature that presents the most difficulty for us as [...]]]></description>
			<content:encoded><![CDATA[<p>Anyone who develops Javascript long enough undoubtedly runs into difficulties involving the various security features all browser vendors implement. These security features are a good thing -- they protect us from malicious users hijacking our browsing experience. But they can certainly cause some headaches. The security feature that presents the most difficulty for us as developers is the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy</a>.</p>
<p>In a nutshell, this policy prevents pages from two different domains from modifying each others properties, using XMLHttpRequest, setting cookies etc. For instance, Example.com and OtherExample.com can't get references to each others <code>document</code> properties and can't set cookies on each other. Additionally, Example.com can't use XMLHttpRequest (aka AJAX) to load a resource from OtherExample.com. This last bit is probably the biggest issue for developers today -- in todays world of open web services and mashups. How do you consume a web service with Javascript if you can't load the data properly?<span id="more-139"></span></p>
<h1>Solution 1: Use a server-side proxy</h1>
<p>The first way around this problem is to use a very simple server-side script that acts as a proxy to the web service. So instead of requesting AJAX from the remote site, you request it locally on your own domain through the proxy. The proxy itself has it's programming logic to send your request off to the remote site, gather the data, and then serve it back to you.</p>
<pre>.________________________.
| Client on YourSite.com |
'-\/---------/\----------'
  ||         ||
  ||_________||__.
  | AJAX Request |
  '---\/-----/\--'
      ||     ||
      ||_____||______________.
      | YourSite.com         |
      | (Ex. ajax_proxy.php) |
      '---\/-----/\----------'
          ||     ||
          ||_____||__________.
          | OtherSite.com    |
          '------------------'</pre>
<p>Since your server-side script has no qualms about fetching data from another domain, you can successfully proxy all AJAX like this without running into any trouble. And then since the client browser is fetching the data from the local domain (even though you're making another request behind the scenes), it doesn't violate the same origin policy.</p>
<p>An example proxy script might look something like this (maybe a little more complex if you're handling POST data too):</p>
<pre id="raw-php-8" style="display:none; width: 1px; height: 1px; overflow: hidden;">$url = 'http://othersite.com/someservice?' . http_build_query($_GET);
echo file_get_contents($url);</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-8" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-8'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-8">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$url</span> = <span style="color:#FF0000;">'http://othersite.com/someservice?'</span> . http_build_query<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <a href="http://www.php.net/file_get_contents"><span style="color:#000066;">file_get_contents</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$url</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p>
Remember, the sole purpose of the proxy is just so the client browser can load the data locally on the same domain so the same origin policy isn't violated.</p>
<h2>Drawbacks</h2>
<p>This method works well but has two obvious drawbacks. First is of course that you need a server-side script at all. Especially if you are providing a service, this raises the barrier for entry and makes it harder for "noobs" to use your widget -- it's not a simple "paste this code into your footer" instruction; you also need to explain how to install the proxy service.</p>
<p>The second drawback is that your own servers are making these requests which makes the whole process slower, but also eats up your resources -- both your processing power and even just simple bandwidth.</p>
<h1>Solution 2: JSONP</h1>
<p>The second solution is to use JSONP -- "JSON with Padding." This is a technique that lets you get around the same origin policy. In order to use JSONP, the service you are requesting needs to support it.</p>
<p>So in the last solution, the consumer (the user using the service) required an ajax_proxy.php or whatever server-side proxy script. In this solution, the provider (Digg, Amazon, Yahoo -- whatever) needs to support JSONP themselves. Thankfully, these days the idea is catching on and it's likely JSONP is an option. And if you're a service provider, then you'll want to build it in to your service for sure.</p>
<h2>How it works</h2>
<p>A normal JSON request is sent using XMLHttpRequest and the reply looks something like this:</p>
<pre id="raw-javascript-9" style="display:none; width: 1px; height: 1px; overflow: hidden;">{'uid': 23, 'username': 'Chroder', 'name': 'Christopher Nadeau'}</pre>
<div class="igBar">
<div class="wrap"><span id="ljavascript-9" style="float:right"><a href="#" onclick="javascript:showCodeTxt('javascript-9'); return false;">Plain Text</a></span><span class="langName">JAVASCRIPT:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="javascript-9">
<div class="javascript">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span><span style="color: #3366CC;">'uid'</span>: <span style="color: #CC0000;color:#800000;">23</span>, <span style="color: #3366CC;">'username'</span>: <span style="color: #3366CC;">'Chroder'</span>, <span style="color: #3366CC;">'name'</span>: <span style="color: #3366CC;">'Christopher Nadeau'</span><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Now the truth is, JSONP isn't AJAX at all technically speaking because it does <em>not</em> use XMLHttpRequest. JSONP requests are made by dynamically inserting a &lt;script&gt; tag into the DOM. For example, you'd insert this:</p>
<pre id="raw-html-10" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;script type=&quot;text/javascript&quot; src=&quot;http://othersite.com/service?all=your&amp;params=as&amp;usual=gohere&quot;&gt;&lt;/script&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lhtml-10" style="float:right"><a href="#" onclick="javascript:showCodeTxt('html-10'); return false;">Plain Text</a></span><span class="langName">HTML:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="html-10">
<div class="html">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/script.html"><span style="color: #000000; font-weight: bold;">&lt;script</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text/javascript"</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">"http://othersite.com/service?all=your&amp;params=as&amp;usual=gohere"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Then that remote Javascript file is loaded and contains an actual Javascript function call. For example:</p>
<pre id="raw-javascript-11" style="display:none; width: 1px; height: 1px; overflow: hidden;">handleJsonReply({'uid': 23, 'username': 'Chroder', 'name': 'Christopher Nadeau'});</pre>
<div class="igBar">
<div class="wrap"><span id="ljavascript-11" style="float:right"><a href="#" onclick="javascript:showCodeTxt('javascript-11'); return false;">Plain Text</a></span><span class="langName">JAVASCRIPT:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="javascript-11">
<div class="javascript">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">handleJsonReply<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #3366CC;">'uid'</span>: <span style="color: #CC0000;color:#800000;">23</span>, <span style="color: #3366CC;">'username'</span>: <span style="color: #3366CC;">'Chroder'</span>, <span style="color: #3366CC;">'name'</span>: <span style="color: #3366CC;">'Christopher Nadeau'</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>In other words, instead of reading AJAX data directly into a variable in Javascript, you define a callback function that is called when the data arrives, and the first parameter is the data itself as an object literal. If you were a provider implementing JSON on your service you might have something like:</p>
<pre id="raw-php-12" style="display:none; width: 1px; height: 1px; overflow: hidden;">// A service provider accepts a 'callback' parameter
// that it uses to wrap an AJAX reply

// Imagine we did some work here
$json = json_encode($mydata);

// Using JSONP
if ($_GET['callback']) {
	echo $_GET['callback'] . &quot;($json);&quot;; // somefunction({data here});

// Normal JSON
} else {
	echo $json;
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-12" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-12'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-12">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// A service provider accepts a 'callback' parameter</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// that it uses to wrap an AJAX reply</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Imagine we did some work here</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$json</span> = json_encode<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$mydata</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Using JSONP</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'callback'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'callback'</span><span style="color:#006600; font-weight:bold;">&#93;</span> . <span style="color:#FF0000;">"($json);"</span>; <span style="color:#FF9933; font-style:italic;">// somefunction({data here});</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Normal JSON</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$json</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>The Javascript source code result of that request is nothing but a real executable function call with a Javascript object literal. It's as if you added the tag yourself and it called some functions -- the difference being that the JS is written by the producer on-the-fly and embeds the data you want right in the code. This is why it all works; it's not actually AJAX at all, it's just loading a remote Javascript file that happens to have some useful data in it.</p>
<p>Using a library like jQuery that supports JSONP, these details of inserting the special script tag and creating the special callback function are all taken care of automatically. Using a JS library, usually the only difference between JSONP and real AJAX is that you enable a 'jsonp' option.</p>
<h2>Drawbacks</h2>
<p>The first limitation to this method is that you have to rely on the provider to implement JSONP. The provider needs to actually support JSONP -- they need to wrap their JSON data with that callback function name.</p>
<p>Then the next limitation -- and this is a big one -- is that JSONP doesn't support POST requests. Since all data is passed in the query string as GET data, you are severely limited if your services require the passing of long data (for example, forum posts or comments or articles). But for the majority of consumer services that <em>fetch</em> more data than they push, this isn't such a big problem.</p>
<h2>JSONP with jQuery</h2>
<p>Step 1: Make sure the provider supports JSONP.<br />
Step 2: Set the <code>dataType</code> option to <code>jsonp</code>, and if the provider uses a different GET param other than 'callback', specify the <code>jsonp</code> option to that parameter name.</p>
<pre id="raw-javascript-13" style="display:none; width: 1px; height: 1px; overflow: hidden;">$.ajax({
    // ... Use the AJAX utility as you normally would
    dataType: 'jsonp',
    // ...
});</pre>
<div class="igBar">
<div class="wrap"><span id="ljavascript-13" style="float:right"><a href="#" onclick="javascript:showCodeTxt('javascript-13'); return false;">Plain Text</a></span><span class="langName">JAVASCRIPT:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="javascript-13">
<div class="javascript">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">$.<span style="color: #006600;">ajax</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900; font-style: italic;">// ... Use the AJAX utility as you normally would</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; dataType: <span style="color: #3366CC;">'jsonp'</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900; font-style: italic;">// ...</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>jQuery will generate a unique callback name for this request (something like json1268267816). Thus, the reply from a web service would be something like:</p>
<pre id="raw-javascript-14" style="display:none; width: 1px; height: 1px; overflow: hidden;">json1268267816({'uid': 23, 'username': 'Chroder', 'name': 'Christopher Nadeau'});</pre>
<div class="igBar">
<div class="wrap"><span id="ljavascript-14" style="float:right"><a href="#" onclick="javascript:showCodeTxt('javascript-14'); return false;">Plain Text</a></span><span class="langName">JAVASCRIPT:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="javascript-14">
<div class="javascript">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">json1268267816<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #3366CC;">'uid'</span>: <span style="color: #CC0000;color:#800000;">23</span>, <span style="color: #3366CC;">'username'</span>: <span style="color: #3366CC;">'Chroder'</span>, <span style="color: #3366CC;">'name'</span>: <span style="color: #3366CC;">'Christopher Nadeau'</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p>
But jQuery handles it all seamlessly, so you as the developer just handle it like a normal AJAX request using the same jQuery success/failure/complete callback hooks.</p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2010/03/10/cross-domain-ajax/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>8 Features of Badly Designed Software</title>
		<link>http://devlog.info/2009/09/16/8-features-of-badly-designed-software/</link>
		<comments>http://devlog.info/2009/09/16/8-features-of-badly-designed-software/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 02:18:05 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Design Patterns]]></category>

		<guid isPermaLink="false">http://devlog.info/?p=89</guid>
		<description><![CDATA[I've compiled a list of 8 features that are inherent to all badly designed software. This list is in regards to code design -- it's about architecture.
1. High Coupling
All software you write depends on some other software. And parts of your own software depends on other parts of your software. Coupling is how much one [...]]]></description>
			<content:encoded><![CDATA[<p>I've compiled a list of 8 features that are inherent to all badly designed software. This list is in regards to code design -- it's about architecture.<span id="more-89"></span></p>
<h2>1. High Coupling</h2>
<p>All software you write depends on some other software. And parts of your own software depends on other parts of your software. Coupling is <em>how much</em> one part of your software depends on another part. In a highly coupled system, lots of parts all depend on each other. In a lowly coupled system, parts are independent from each other as much as possible.</p>
<h3>Why It's Bad</h3>
<ul>
<li>Changes made to one part of your system affect other parts of your system. This means making changes becomes difficult and error prone.</li>
<li>It becomes difficult or impossible to use even functionally unrelated modules separately because they depend on each other so heavily.</li>
<li>Due to the previous point, it is nearly impossible to write unit tests. This compounds the problem of making changes because you can't properly test to see if your changes break things in other parts of your system.</li>
</ul>
<h3>Solution</h3>
<p>Stop coupling! Write classes that are as separate from each other as you can. This may mean building utility classes, or classes that help "connect" bits of your system. The point is that Part A of your system should be completely separate from Part B of your system.</p>
<h3>Further Reading</h3>
<ul>
<li><a href="http://www.codeodor.com/index.cfm/2009/6/17/Strive-for-low-coupling-and-high-cohesion-What-does-that-even-mean/2902">Strive for low coupling and high cohesion: What does that even mean?</a>
</li>
</ul>
<h2>2. Premature Optimization</h2>
<p>We've all heard the famous quote by Donald Knuth, the author of The Art of Computer Programming: <em>Premature optimization is the root of all evil.</em></p>
<p>Developers often worry about the performance of their software before performance should be considered at all.</p>
<h3>Why It's Bad</h3>
<ul>
<li>A developer who writes code with performance as a first priority will produce code that is hard to use and maintain.</li>
<li>Code that is "optimized" prematurely rarely ever results in software that actually runs faster. Without proper testing/benchmarking, it is often hard to know which parts of your system is the bottleneck. Saving 15 milliseconds on a calculation routine does nothing for the data-fetching routine that takes 1500 milliseconds.</li>
<li>Due to the lack of proper testing, developers will spend too much time on menial performance optimizations while missing the important ones.</li>
</ul>
<h3>Solution</h3>
<p>Write your code with performance in your mind -- but don't sacrifice usability and maintainability. Write your code first, and then only once you have identified real bottlenecks you can start optimizing.</p>
<h2>3. Abusing Inheritance </h2>
<p>Inheritance is great, but some developers try to force their software to fit into rigid inheritance trees. Inheritance is a tool, but it's not the only way to write reusable software.</p>
<h3>Why It's Bad</h3>
<ul>
<li>Abusing inheritance results in classes that have functionality that they shouldn't.</li>
<li>Subclasses make assumptions about their parent classes. This couples children to their parents. As we know, coupling is bad. The deeper our class tree gets, the more coupling, and the worse the design is.</li>
<li>You end up with huge families of classes. For example: A parent Animal class. Then a Dog child. Then a BlackDog, and a BlackBigDog, and BlackSmallDog, and BlackBigLoudDog and BlackSmallLoudDog... You can see how it quickly gets out of control!</li>
<li>You tie functionality/algorithms to a specific family of classes, making it harder to reuse. The only way to access such functionality is through inheritance -- even when inheritance doesn't exactly fit the bill.</li>
</ul>
<h3>Solution</h3>
<p>The old maxim: <em>Favor composition over inheritance</em>.</p>
<p>Composition <em>adds</em> functionality at runtime -- giving you much flexibility. Inheritance forces you to define all functionality at code-time, limiting possibilities.</p>
<p>Composition means your classes are built up (composed) of other classes for additional functionality. This reduces needless children, and decouples functionality into separate reusable classes of their own. Using the example mentioned previously, a Dog class might be made up of separate classes to define it's appearance (AnimalSize class?) and loudness of it's bark (AnimalSound class?). An example calls might then be, <var>$dog->getSize()->display()</var> and <var>$dog->getSound()->makeSound()</var>.</p>
<p>In other words, you want "HAS A" (composition) relationships rather than "IS A" (inheritance) relationships.</p>
<h2>4. Failure to separate responsibilities</h2>
<p>Some developers fall into the trap of creating classes that do way too much -- so called God Objects. Classes should do one thing only (see the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single responsibility principle</a>).</p>
<h3>Why It's Bad</h3>
<ul>
<li>Other parts of your system depend too much on a single class, creating very high coupling. Any changes made will ripple out to all it's dependants.</li>
<li>It is hard to reuse code written in these classes because they come with so much "baggage". Instantiating such a monster object wastes resources with all of the unneeded functionality that has been added.</li>
</ul>
<h3>Solution</h3>
<p>Refactor. The God Object needs to be properly deconstructed into smaller, more specialized classes that all do a single job.</p>
<h2>5. Failure to refactor</h2>
<p>Refactoring is the activity of switching around your softwares internal design, while keeping it's functionality the same. For example, renaming a method is a small example of refactoring. A more intense example might be splitting one class into two separate classes (maybe you're tearing apart a God Object?).</p>
<h3>Why It's Bad</h3>
<ul>
<li>As your product grows older and you add new features, classes will start to gain functionality they did not before. Over time, classes may become too big resulting in monster or God Objects.</li>
<li>As your product grows and you add features, some classes may start to become complex. Without refactoring to simplify the inner workings of your system, this complexity may start to get out of control. For example, a class constructor that takes 20 arguments.</li>
<li>The longer refactoring is put off, the worse the problem becomes and the harder the task will be in the future.</li>
</ul>
<h3>Solution</h3>
<p>Refactor as soon as you encounter <a href="http://en.wikipedia.org/wiki/Code_smell">smelly code</a>. The earlier you refactor, the easier it will be.</p>
<h2>6. Complexity</h2>
<p>Code should be simple to read and maintain. Functions that take 20 arguments, or classes that require too many helper objects are examples of complex designs that can be fixed.</p>
<h3>Why It's Bad</h3>
<ul>
<li>Complex designs are hard to understand and thus hard to maintain.</li>
<li>Complex designs will result in hard to find bugs.</li>
</ul>
<h3>Solutions</h3>
<p>Simplify. If a function takes 20 arguments, maybe some of those arguments can be encapsulated into a class. Or maybe the one function can be replaced by an easier to use class. If a class requires lots of setup, consider using the <a href="http://en.wikipedia.org/wiki/Builder_pattern">Builder pattern</a>. If you have a system of classes that all work together towards some goal, consider simplifying the interface by using a <a href="http://en.wikipedia.org/wiki/Facade_pattern">Facade</a>.</p>
<h2>7. Reinventing The Wheel</h2>
<p>Some developers, especially amateurs, like to create everything from scratch and ignore all of the available free library code that exists on the internet.</p>
<h3>Why It's Bad</h3>
<ul>
<li>You waste time writing components when you could be actually building your product.</li>
<li>You get none of the free testing done against a popular library. Anything you write from scratch will contain bugs.</li>
<li>Not always true (but may especially apply to amateurs): Many libraries are written by developers who may be more experienced than you. These coders produce better organized code with more features.</li>
<li>Not always true: Developers of libraries are often experts in whatever task the library is meant to solve. For example, database abstraction. Because of this, the library developers will produce a better product than you could.</li>
</ul>
<h3>Solutions</h3>
<p>Realize that writing everything in-house is almost always a bad thing. There will of course be times where there exists no suitable library. But almost everything has been written before, and written well. A good developer knows the tools at his disposal, and uses them.</p>
<p>Every time you consider writing something yourself, you should search for a good library first. Common difficult tasks such as database abstraction, web services, image manipulation, validation and parsing are examples of components where an abundance of free library code exists. Less well-known problems, or new problems, may not have many pre-built solutions.</p>
<h2>8. Failure to apply known design patterns</h2>
<p><a href="http://en.wikipedia.org/wiki/Design_patterns">Design patterns</a> are well known solutions to architectural problems in software. I've mentioned a couple in this article already (Builder, Facade).</p>
<h3>Why It's bad</h3>
<ul>
<li>A developer who doesn't know design patterns is more likely to design his software incorrectly.</li>
<li>Not knowing about design patterns will decrease your efficiency. Every problem has been solved before. By knowing which pattern to apply to a problem, half of your work is done for you. Otherwise, you will go through many revisions before you end up at the same solution anyway.</li>
<li>Design patterns help a developer communicate with other developers. It's the language of the profession. You will not be able to convey ideas effectively if you don't understand the terminology.</a>
</ul>
<h3>Solution</h3>
<p>Read all material you can find on the topic of design patterns (see next section). Amateur programmers may not appreciate the value of these patterns at first -- or, indeed, may not fully understand them -- but as time goes on, this knowledge is priceless.</p>
<h3>Further Reading</h3>
<ul>
<li><a href="http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124">Head First Design Patterns</a></li>
<li><a href="http://www.amazon.ca/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612"> Design Patterns: Elements of Reusable Object-Oriented Software</a></li>
<li><a href="http://www.amazon.ca/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420"> Patterns of Enterprise Application Architecture</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2009/09/16/8-features-of-badly-designed-software/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MVC With The Zend Framework</title>
		<link>http://devlog.info/2008/04/08/mvc-with-the-zend-framework/</link>
		<comments>http://devlog.info/2008/04/08/mvc-with-the-zend-framework/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 01:24:52 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://devlog.info/?p=28</guid>
		<description><![CDATA[I've been using the Zend Framework a lot lately and have come to really appreciate it. Today I want to write about ZF and how to use the MVC components. This post will be all about ZF itself, how the MVC components work, and getting a simple example up and going. I will write another [...]]]></description>
			<content:encoded><![CDATA[<p>I've been using the Zend Framework a lot lately and have come to really appreciate it. Today I want to write about ZF and how to use the MVC components. This post will be all about ZF itself, how the MVC components work, and getting a simple example up and going. I will write another post later on some more advanced usage.<span id="more-28"></span></p>
<h2>About Zend Framework</h2>
<p>The <a href="http://framework.zend.com/">Zend Framework</a> is a free (<a href="http://framework.zend.com/license">BSD-like</a> license) PHP framework. It contains components to tackle many common problems including authentication, cacheing, mail, sessions, and of course MVC.</p>
<p>ZF is simple. It is a "use at will" framework, meaning you can take specific components and use them wherever you want. You can, for example, take just the Mail component and stick it into your already existing PHP application. This decoupled architecture is contrary to some other frameworks (including symfony or CakePHP to certain extents) where you are forced into using a single paradigm.</p>
<p>This framework is written for PHP5 only, so it is not encumbered by the limitations of PHP4. It is written using the best OOP principals, is thoroughly tested, and has a marvelous community of maintainers that keep it up to date.</p>
<h3>Zend Framework versus other frameworks (symfony, CakePHP etc)</h3>
<p>Typically when you think of a framework, you envision a completely developed codebase that includes its own of configuration, its own conventions, and specific programming paradigms. Many frameworks including <a href="http://www.symfony-project.com/">symfony</a>, <a href="http://cakephp.com/">CakePHP</a>, <a href="http://codeigniter.com/">Code Igniter</a> and Ruby's <a href="http://www.rubyonrails.org/">Rails</a>, follow this kind of thinking.</p>
<p>Zend Framework is a collection of loosely coupled components. As mentioned earlier, you can use any one of the components separately without running into any problems. Even so, the components still work very well together (for example, Zend_Auth can seamlessly use Zend_Session for persistence).</p>
<p>You need to do a bit more work to use ZF initially. ZF is not all tied together, so if you want to use MVC  (for example) then you have to create your own bootstrap, and create your own directory structure etc. When you download ZF it's simply a directory that contains the library files, you're the one who has to initialize and use everything. Compare this to symfony (or many others) where everything is ready to go after you edit a couple configuration lines.</p>
<p>I prefer ZF because I feel like I have more control. I am not tied into any one paradigm, I don't need to play around with configuration files and I can mix and match my code to my hearts content. </p>
<p>Please note that I am not belittling the other frameworks, I am just trying to explain what sets ZF apart. If you read some of my previous posts, you'll see I'm also an advocate of symfony.</p>
<h2>The Parts</h2>
<p><a href="http://devlog.info/2007/06/27/php-model-view-controller/">MVC</a> with Zend Framework is quite easy. Here's a brief overview of each part and how they relate to each other.</p>
<h3>1. Front Controller</h3>
<p>Most people will use a <a href="http://www.martinfowler.com/eaaCatalog/frontController.html">Front Controller</a>. Using a Front Controller means that all requests come through a central starting point. Usually a single index.php will instantiate the front controller object and handle all incoming requests to your site. The file is referred to as a "bootstrap" file, and will contain code to initialize other things in your system too (for example, loading configuration settings).</p>
<p>If you've been developing on the web for a while, you've probably seen lots of scripts that have many entry points. For example, you might have index.php, login.php, article.php etc. Most of the time you also have a global.php file that is included at the top of each script. When you have all these entry points, it can quickly become hard to manage and you also start to get a bunch of code duplication.</p>
<p>A Front Controller solves this. Instead of physical files on the disk defining how a request should be handled, the request itself is entered through the Front Controller and then analyzed to see what should be done with it.</p>
<h3>2. The Request Object</h3>
<p>Each request made has a corresponding Request object. This object wraps up the entire request environment. For example, the default HTTP environment contains things like request parameters from GET and POST. The Request object also contains which controller and action should be called upon.</p>
<h3>3. The Router</h3>
<p>The Router is what actually inspects the incoming request and decides which Controller and Action should be called up. For example, it will look at a request of /login and decide that the Login Controller should handle the request, and the Index Action should be called.</p>
<p>ZF comes with a default router, so you don't need to change anything unless you want special behavior. By default, the incoming URL is analyzed and the parts are mapped to specific controllers and actions: /:controller/:action. If they are not provided at all, then they are assumed to be 'index'.</p>
<h3>3. The Dispatcher</h3>
<p>Dispatching is the process of looking at the requested controller and action, and actually including the correct Controller file, instantiating it, and calling on the action. The Dispatcher is in a loop. That means you can run as many controllers and actions as you like.</p>
<p>Again, ZF comes with a default dispatcher that sets down some naming conventions that we'll explore in a bit.</p>
<h3>4. The Controller</h3>
<p>Finally there is your actual controller. A controller handles a specific part of your app (for example, working with articles) and can have multiple actions (for example, listing articles, viewing a single article, viewing a printable version etc).</p>
<h2>The Process</h2>
<p>A request is handled like so:</p>
<ol>
<li>A web request is made to a single entry point (usually an index.php file)
<li>The entry point creates a Front Controller and runs it</li>
<li>The Front Controller creates a Request object that wraps up the environment. At this point there is no controller or action set.</li>
<li>The Front Controller uses a Router to inspect the request to figure out which controller and action should be called upon. It sets these values in the Request object.</li>
<li>The Front Controller starts the Dispatcher loop which includes the correct Controller source file, instantiates it, and runs the correct Action.</li>
<li>A Controller does what it does. It can handle forms, get database info, render HTML etc.</li>
<li>Any Controller can also modify the Request object and set a different Controller or Action, so the Dispatch loop is run again. If no change is made, then the Dispatch loop ends and the result is served to the user</li>
</ol>
<p>You can get a visual representation of the process by viewing <a href="http://framework.zend.com/manual/en/figures/zend.controller.basics.png">this image</a>.</p>
<h2>Let's Get Started</h2>
<h3>The File Structure</h3>
<p>I like to separate my files into two parts. One part for the actual application files (controllers, libs, views, functions etc) and then public files that the user needs access to (javascript, css, images etc).</p>
<p>For the sake of simplicity, I also like to package ZF with my app. If you have a shared directory where you place libraries (PEAR, for example), then you of course don't need to include it with your own files.</p>
<p>Here's the structure I use:</p>
<ul>
<li>root
<ul>
<li>/client
<ul>
<li>/css</li>
<li>/images</li>
<li>/js</li>
</ul>
</li>
<li>/appfiles
<ul>
<li>/application
<ul>
<li>/controllers</li>
<li>/views
<ul>
<li>/scripts</li>
</ul>
</li>
</ul>
</li>
<li>/lib
<ul>
<li>/Zend</li>
</ul>
</li>
</ul>
</li>
<li>/.htaccess</li>
<li>/index.php</li>
</ul>
</li>
</ul>
<p>This also makes it easy to split up the appfiles from the public files. For example, may people like to place the application source files outside of the document root on the webserver.</p>
<p>The /appfiles/application directory contains all of your controller and view files. We'll talk about the naming convention the default Dispatcher expects in a sec.</p>
<p>The /appfiles/lib directory is where I personally like to keep the Zend Framwork files.</p>
<p>You can of course have any other directories you'd like. On one of my recent projects I had /appfiles/functions and /appfiles/classes for some various custom code files.</p>
<h3>Rewrite URLs</h3>
<p>To create friendly URL's like /login or /article/view, you need a way to rewrite all URL's to go through the main index.php file. If you are using an Apache webserver and htaccess is a viable option, then the following simple code snippet should work fine for you:</p>
<pre id="raw-code-19" style="display:none; width: 1px; height: 1px; overflow: hidden;">RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php</pre>
<div class="igBar">
<div class="wrap"><span id="lcode-19" style="float:right"><a href="#" onclick="javascript:showCodeTxt('code-19'); return false;">Plain Text</a></span><span class="langName">CODE:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="code-19">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">RewriteEngine on</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">RewriteRule !\.<span style="color:#006600; font-weight:bold;">&#40;</span>js|ico|gif|jpg|png|css<span style="color:#006600; font-weight:bold;">&#41;</span>$ index.<span style="">php</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p>
If you are on a different server, there are <a href="http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.introduction">other ways</a> to rewrite URLs.</p>
<p>Note that you can still use ZF's MVC components without rewriting URL's. Refer to the documentation for info on how to do this.</p>
<h3>Create Bootstrap</h3>
<p>The bootstrap file is the "single entry point" I've been talking about. It contains the code that launches the Front Controller. In this case, our bootstrap file is index.php.</p>
<p>Here's the code for a simple bootstrap file:</p>
<pre id="raw-php-20" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php

#------------------------------
# Get the paths set
#------------------------------

define('ROOT', realpath(dirname(__FILE__) . '/appfiles'));
set_include_path('.' . PATH_SEPARATOR . ROOT . PATH_SEPARATOR . ROOT.'/lib');

#------------------------------
# Register the Zend autolaoder
#------------------------------

require_once(ROOT . '/lib/Zend/Loader.php');
Zend_Loader::registerAutoload();

#------------------------------
# Dispatch
#------------------------------

Zend_Controller_Front::run(ROOT . '/application/controllers');</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-20" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-20'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-20">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;"># Get the paths set</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/define"><span style="color:#000066;">define</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'ROOT'</span>, <a href="http://www.php.net/realpath"><span style="color:#000066;">realpath</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/dirname"><span style="color:#000066;">dirname</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#000000; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <span style="color:#FF0000;">'/appfiles'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/set_include_path"><span style="color:#000066;">set_include_path</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'.'</span> . PATH_SEPARATOR . ROOT . PATH_SEPARATOR . ROOT.<span style="color:#FF0000;">'/lib'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;"># Register the Zend autolaoder</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">require_once</span><span style="color:#006600; font-weight:bold;">&#40;</span>ROOT . <span style="color:#FF0000;">'/lib/Zend/Loader.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Zend_Loader::<span style="color:#006600;">registerAutoload</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;"># Dispatch</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Zend_Controller_Front::<span style="color:#006600;">run</span><span style="color:#006600; font-weight:bold;">&#40;</span>ROOT . <span style="color:#FF0000;">'/application/controllers'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Line 7 defines the <em>ROOT</em> constant to be the full path to the appfiles/ directory. If you were to move the appfiles/ directory somewhere else, you'd want to edit this line so the path stays correct.</p>
<p>Line 8 sets the PHP include path so that the Zend files are all included without any problems. We need this line because we are distributing ZF with the project, we need to tell PHP where to look for the files when we include them.</p>
<p>Line 15 and 16 include Zend_Loader and register it's autoload functionality. PHP5 introduced the ability to <a href="http://php.net/autoload">autoload</a> classes. Whenever a class is used but has not been defined, PHP will try and find the file and include it for you. This saves you from having to manually write all of the require_once()'s you would normally write under PHP4.</p>
<p>Line 23 fires off the Front Controller which starts up your whole application. As a parameter you need to pass the path to your controller files which in our case is /appfiles/application/controllers.</p>
<p>If you run this now (http://yoursite.com/path/to/project/), you'll see an exception because ZF can't find your controller file to handle the request. So let's write it.</p>
<h2>Controllers and Actions</h2>
<h3>What are Controllers? Actions?</h3>
<p>Lets get this question out of the way for those who are new to this kind of website architecture. A Controller is a class that handles the business logic of a given part of your website. It fetches data from a datasource, interacts with output, and then passes any calculations to the View to be displayed to the user (usually as HTML). Some examples of Controllers might be: LoginController, ArticleController and SearchController. Before you might have had files like login.php, article.php and search.php -- now you have classes that control all of this behavior.</p>
<p>Each Controller has a set of Actions, which is just a method you define within the Controller class. An Action is something specific the Controller needs to do. Using our examples listed before, this might be <em>processing</em> a login, <em>displaying</em> an article or <em>performing</em> a search. Before you might have used a variable in the URL to determine what needed to be done. For example, "article.php?do=display" now becomes the ArticleController with the 'display' Action.</p>
<h3>Naming Conventions</h3>
<p>So you know that controllers are classes, and actions are methods in the controllers. Now the only thing left to cover is how ZF knows which file to load, and which method to call.</p>
<p>You defined the location of the controller files when you called Zend_Controller_Front::run() in the bootstrap. In our example, it is /appfiles/application/controllers.</p>
<p>The Dispatcher (explained above) is responsible for loading the appropriate files, instantiating the correct class, and then calling the correct method. The default Dispatcher that comes with ZF uses a naming convention so you can add controllers and actions easily (instead of say, creating a configuration file that defines it all).</p>
<p>There are two very simple rules:</p>
<ul>
<li>All controllers need to be called SomethingController where "Something" can be whatever you want. The class source code needs to be in a file called "SomethingController.php".</li>
<li>All actions need to be called someAction() where "some" is anything you want.</li>
</ul>
<p>The default Router and Dispatcher will route a URL /something/some to the SomethingController and the someAction() action. (Meaning: Remember that the default URLs are /:controller/:action).</p>
<p>If a controller is not specified, then the 'index' controller (IndexController class) will be assumed. If an action is not specified, then the 'index' action is assumed (indexAction() method).</p>
<p>Just to hammer it into your head, let's have a few examples of how some possible URLs might be loaded using the default Router and Dispatcher:</p>
<ul>
<li>/: IndexController class, indexAction() method</li>
<li>/login: LoginController class, indexAction() method</li>
<li>/login/lostpass: LoginController class, lostpassAction() method</li>
<li>/article/new: ArticleController class, newAction() method</li>
</ul>
<p>You can also use hyphens in your URL's if you use camelCase in the naming of controllers or actions:</p>
<ul>
<li>/download/message-attachment: DownloadController class, messageAttachmentAction() method</li>
<li>/sign-up/confirm-email: SignUpController class, confirmEmailAction() method</li>
</ul>
<h2>Views</h2>
<h3>What are Views?</h3>
<p>A View is the thing that you give back to the user after they request something. Usually this is an HTML page, but it can be other things like XML or RSS feeds,  file downloads etc.</p>
<h3>File Locations</h3>
<p>Controllers will try to render a view script automatically. It will search for view scripts in /views/scripts/ in the directory above the controller directory (for us that means /appfiles/applications/views/scripts/). Each controller is expected to have a directory of its own, and each action is expected to have a .phtml file that is the actual PHP script to render. For example, LoginController's indexAction() will have a view in views/scripts/login/index.phtml.</p>
<h3>View Files</h3>
<p>The default view scripts in ZF are plain old PHP. You can add a different templating system if you'd like (like Smarty), but for simplicity, this article will use the default.</p>
<p>In the controller you can set variables to be available to the view, so you can do all of the usual stuff you'd expect like looping, formatting etc.</p>
<h2>An Example Page</h2>
<p>Time for a really simple example page that demonstrates everything you've just read.</p>
<p>First step is creating a new controller. This controller will be located at: /appfiles/application/controllers/IndexController.php with the following code:</p>
<pre id="raw-php-21" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php

class IndexController extends Zend_Controller_Action {
    public function indexAction() {

        $this-&gt;view-&gt;name = &quot;Christopher&quot;;

    }
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-21" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-21'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-21">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">class</span> IndexController extends Zend_Controller_Action <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> indexAction<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">view</span>-&gt;<span style="color:#006600;">name</span> = <span style="color:#FF0000;">"Christopher"</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Next we need to create a view script to render the HTML page. The view script will be located at: /appfiles/application/views/scripts/index/index.phtml with the following code:</p>
<pre id="raw-html-22" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;h1&gt;Hi, &lt;?php echo $this-&gt;name; ?&gt;&lt;/h1&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lhtml-22" style="float:right"><a href="#" onclick="javascript:showCodeTxt('html-22'); return false;">Plain Text</a></span><span class="langName">HTML:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="html-22">
<div class="html">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/h1.html"><span style="color: #000000; font-weight: bold;">&lt;h1&gt;</span></a></span>Hi, <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span></a>?php echo $this-<span style="color: #000000; font-weight: bold;">&gt;</span></a></span>name; ?&gt;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h1&gt;</span></span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Now if you run this in your browser, you'll get a simple page that displays a name. So what is going on here?</p>
<h3>The Controller</h3>
<p>The IndexController is a class the extends Zend_Controller_Action. All of your controllers must extend this base class (or a child of this base class -- you can create your own if you needed to). And on line 4 we have defined the indexAction() method to handle the default index action.</p>
<p>By defining both the index controller with an index action, we now have a default page do display whenever there was no URL supplied (remember that the dispatcher assumes 'index' if no controller or index was supplied).</p>
<p>On line 6 you'll notice we are assigning a name to a variable $this->view->name. This is how you pass values to your view script. You can assign any values. The view script is just PHP remember, so it doesn't matter if you assign arrays, objects, integers or strings.</p>
<h3>The View</h3>
<p>The view in our case is very simple. I just wanted to highlight how we use the variables assigned in the controller. All values assigned in the controller are available as $this->varname.</p>
<h2>What about Models?</h2>
<p>I haven't discussed anything about the models in this article. That's because the model in ZF's MVC can be just about anything.</p>
<p>A <em>model</em> is an object, or a system of objects, that represent some sort of data. Most often models are objects that represent specific database records, or database tables. For example, if you have a "user" table then you'd also have a "User" object to represent records from the table. You might also have a "UserTable" object to make finding records easier (sometimes called "peer objects"). So you might have classes with methods like User::setPassword() and UserTable::findUserByEmail(). This technique of mapping a table to objects is the <a href="http://martinfowler.com/eaaCatalog/activeRecord.html">ActiveRecord</a> pattern.</p>
<p>You can code these objects yourself, but usually some sort of ORM (Object-relational mapping) tool/library is used. Two of the most popular are <a href="http://www.phpdoctrine.org/">Doctrine</a> and <a href="http://propel.phpdb.org/trac/">Popel</a> (I suggest Doctrine). With these libraries, you define the structure of your database and the rest of the work is done for you. That is, the means of satisfying relationships and filling data objects with actual data form the database is done by the library rather then by hand. In the case of Doctrine, actual SQL is abstracted into so-called "DQL" (Doctrine Query Language) to make your programs 100% portable.</p>
<p>The point of a model is to create a separation between the data-tier and the logic-tier in your application. For example, your application's "change password" controller shouldn't need to know the low-level details of how a password is changed (the hashing, salting etc). That kind of thing should be coded into the model.</p>
<h2>Finished</h2>
<p>That's all there is to it. <a href='http://devlog.info/wp-content/uploads/2008/04/devlog-zf-mvc.zip'>Click here</a> to download the sample files used in this article (note that you need to add your own Zend library to the /appfiles/lib directory).</p>
<p>Next article I will go over some more advanced techniques including subclassing the front controller, action controllers, creating plugins and creating helpers.</p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2008/04/08/mvc-with-the-zend-framework/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Intro to the MVC Pattern</title>
		<link>http://devlog.info/2007/06/27/php-model-view-controller/</link>
		<comments>http://devlog.info/2007/06/27/php-model-view-controller/#comments</comments>
		<pubDate>Wed, 27 Jun 2007 21:31:16 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://devlog.info/2007/06/27/php-model-view-controller/</guid>
		<description><![CDATA[There's a lot of talk these days about design patterns. The most talked about pattern in the realm of web development seems to be the MVC pattern, or the Model-View-Controller. It is this pattern that many of the most popular frameworks are built around. Frameworks like symfony, CakePHP and CodeIgniter enforce this pattern and offer [...]]]></description>
			<content:encoded><![CDATA[<p>There's a lot of talk these days about design patterns. The most talked about pattern in the realm of web development seems to be the MVC pattern, or the <em>Model-View-Controller</em>. It is this pattern that many of the most popular frameworks are built around. Frameworks like <a href="http://www.symfony-project.com/">symfony</a>, <a href="http://cakephp.org/">CakePHP</a> and <a href="http://codeigniter.com/">CodeIgniter</a> enforce this pattern and offer tools to help make using it a breeze. Ruby's famous <a href="http://rubyonrails.com/">Rails</a> framework and Perl's <a href="http://www.catalystframework.org/">Catalyst</a> also make use of the MVC pattern. So what is the big deal? Should you care? In this post I'm going to briefly try and explain the MVC pattern, why you should use it, and how.<span id="more-19"></span></p>
<h2>What is What</h2>
<p>The MVC pattern is made up of three separate parts -- the Model, View and Controller. In this section we'll explore each part and what they are supposed to do.</p>
<h3>The Model</h3>
<p>The Model is the thing that takes care of the data in your application. It offers ways to find and retrieve data, ways to save data, etcetera. In a lot of cases your model might be a simple class that is just a map of a database table. Many of the web frameworks like symfony give you tools to automatically generate a PHP class that has all of the properties and methods for any particular database schema you have. For example, a <em>users</em> table might have a corresponding <em>User</em> class with methods like <em>User::findByUsername()</em> and <em>User::setEmail()</em>.</p>
<p>The important thing is that you encapsulate the domain logic. Sometimes all the model needs to do is retrieve rows from a database or read data from a file. Other times additional processing may be needed, like calculating the users age based on a birth date.</p>
<h3>The View</h3>
<p>The View takes the data from the Model and displays it in a useful way. In web applications this usually means that the data from the Model is displayed in an HTML page. Some other Views might be for generating an RSS feed or data for a web service. By separating the Model and the View, you can easily switch things up to create new interfaces to the data without much work at all.</p>
<p>Note that keeping the Model and the View separate does not mean that you can't get direct access to the Model itself. In many cases you will be using the Model directly. To output a users username you might use the Model and call <em>User::getUsername()</em> and output it. The idea is only that you separate the domain logic from the presentation. For example, you might have some sort of subscription service. If you wanted to output a message when the users subscription is expired it might seem logical to do something like this within the View:</p>
<pre id="raw-php-25" style="display:none; width: 1px; height: 1px; overflow: hidden;">Welcome back, &lt;?php echo $user-&gt;getUsername(); ?&gt;!

&lt;?php if ($user-&gt;getSubscriptionExpiry() &lt;time()): ?&gt;
    Your subscription has expired. Please renew.
&lt;?php endif; ?&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-25" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-25'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-25">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Welcome back, <span style="color:#000000; font-weight:bold;">&lt;?php</span> <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$user</span>-&gt;<span style="color:#006600;">getUsername</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#000000; font-weight:bold;">?&gt;</span>!</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$user</span>-&gt;<span style="color:#006600;">getSubscriptionExpiry</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> &lt;time<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>: <span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Your subscription has expired. Please renew.</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">endif</span>; <span style="color:#000000; font-weight:bold;">?&gt;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>This is mixing domain logic with the presentation. You are hard-coding what "expired" means directly into the View. If a time came when you needed to change the criteria for when a user is considered expired, then you'd need to go back into every file and change this hard-coded definition. Instead, you should create a method in the Model:</p>
<pre id="raw-php-26" style="display:none; width: 1px; height: 1px; overflow: hidden;">class User {
    // ....

    public function isExpired() {
        return ($this-&gt;getSubscriptionExpiry() &lt;time());
    }

    // ...
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-26" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-26'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-26">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// ....</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> isExpired<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">getSubscriptionExpiry</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> &lt;time<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// ...</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<h3>The Controller</h3>
<p>The Controller is the part that connects the Model and the View so they can work together. Each part should be quite separate. That is, the Model should not have any code in it for outputting HTML (or any presentation) and the View shouldn't worry about things like fetching results and calculating user expiration dates. Since the two are completely separate for the most part, you need a Controller in the middle that connects them and makes the whole shebang work.</p>
<p>The Controller takes data such as input and works with it. In web apps this usually means taking information from the URL or forms, processing it, and then outputting a web page as a result. For example, if a user wants to update their email address then the the Controller will take the new email address from the form input, use the Model to update the record in the database, and then show a success page to the user using the View.</p>
<p>Here's how a request might be handled:
<ol>
<li>A request comes in</li>
<li>The controller looks at the incoming data like the query string or form data</li>
<li>The controller might need to work with the model to fetch the requested data or to update it. For example, using <em>User::findByUsername()</em> to search for a particular user or <em>User::setEmail()</em> to update an email address.</li>
<li>Then the controller invokes the view to output a result. This might be a page with all the information for the requested user, or a success page after the email address was saved.</li>
</ol>
<h3>What Is Each Part</h3>
<p>We've explored what each part should do, but you still might be confused as to what each part actually is. Is it a file? A class? What?!</p>
<p>The thing is, the MVC is only a patten. There is no single right way to implement it. A Model is can be a single class that encapsulates all the work needed. But by no means does it need to be a single class. It is not uncommon for a Model to consist of multiple classes. For example, one class that is responsible for encapsulating the data and working with it, and another class that is responsible for actually fetching the data. A lot of the time one Model may depend on another Model to satisfy related data like connecting a web order to a user account that made the order.</p>
<p>The Controller is just a single class at it's most basic form. You might have a single class and each method is defined to handle one type of request (list users, edit user, search users etcetera). But again, it is not uncommon for a Controller to be made up of several different parts.</p>
<p>The View can be almost anything. In web applications it is usually a template that is evaluated with data gathered by the controller. You can use simple PHP files like demonstrated earlier, or a template system like Smarty.</p>
<p>The important part of using the MVC pattern is just the way that all these parts are separated form each other.</p>
<h2>Why</h2>
<p>Why use this pattern? At first glance it seems like it's a lot of extra work. If you wanted to make a list of users for example, then a simple list_users.php script that does a database query and outputs some HTML seems like it should take 15 minutes. If you use the MVC pattern, you'll have to think about creating the model first, and then the separate template files for the view, and then you have to worry about the controller to glue them together.</p>
<p>All valid points. It is true that the MVC pattern requires a bit more work. But as soon as you have laid down the foundation, it will make your life so much easier. While some changes may require edits in each part, like a dramatic change to the model might need changes made to the controller and view, you'll also get away with other changes more easily (remember our user expiration example?). More then that though, by keeping these three parts separate you allow yourself the possibility to interchange them. For example, using just one single model you can easily create a number of different interfaces to the data. Imagine how easy it would be to create an HTML page, an RSS feed and an XML data provider. In fact, all three of these things might even share a common Controller and only use separate Views. Adding a web service to interact with the data is as simple as creating a new controller to handle requests.</p>
<p>Try the MVC for your next project, you'll be glad you did.</p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2007/06/27/php-model-view-controller/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
