<?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>PapayaSoft</title>
	<atom:link href="http://www.papayasoft.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.papayasoft.com</link>
	<description>Phuket web development</description>
	<lastBuildDate>Mon, 30 Apr 2012 09:33:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Accessing Zend Framework application resources and config options in module bootstraps</title>
		<link>http://www.papayasoft.com/2012/04/30/accessing-zend-framework-application-resources-module-bootstraps/</link>
		<comments>http://www.papayasoft.com/2012/04/30/accessing-zend-framework-application-resources-module-bootstraps/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 09:32:56 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[zendframework]]></category>
		<category><![CDATA[bootstrap]]></category>
		<category><![CDATA[resources]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=457</guid>
		<description><![CDATA[In a module-enabled ZF1 app, accessing app-level config options and resources from a module-level bootstrap class is easy. Well, once you know how.]]></description>
			<content:encoded><![CDATA[<p>A quick post to document something I tripped over today. As usual, mostly for my own benefit since there is a decent chance that I&#8217;ll completely forget it the next time I need it.</p>
<p>I had a Zend Framework 1.11 app using <code>Zend_Application</code> and its bootstrap process. The application had several modules. So, in <code>application/configs/application.ini</code>:</p>
<pre class="brush:text">
resources.modules.front = "front"
resources.modules.auth  = "auth"
resources.modules.admin = "admin"
</pre>
<p>And each module bootstrap class extended <code>Zend_Application_Module_Bootstrap</code>. For example, the bootstrap class for the module named &#8220;front&#8221; looked like:</p>
<pre class="brush:php">
class Front_Bootstrap extends Zend_Application_Module_Bootstrap
{
    protected function _initSomething()
    {
        // init something
    }
}
</pre>
<p>And there were some app-level application resources &#8211; like cachemanager, for example &#8211; that were defined in the usual way:</p>
<pre class="brush:plain">
resources.cachemanager.feed.frontend.name = Core
resources.cachemanager.feed.frontend.options.lifetime = 21600
resources.cachemanager.feed.frontend.options.automatic_serialization = true
resources.cachemanager.feed.backend.name = File
resources.cachemanager.feed.backend.options.cache_dir = APPLICATION_PATH "/../data/cache"
</pre>
<p>All straightforward and working fine, as it has on many previous occasions.</p>
<p>In my module bootstraps, I was registering some front-controller plugins that needed to access those bootstrapped application resources and config data (the cachemanager resource and a feed url, respectively) that were all specified at app-level. So, I tried to access them in the module-level bootstrap using:</p>
<pre class="brush:php">
class Front_Bootstrap extends Zend_Application_Module_Bootstrap
{
    protected function _initSomething()
    {
        // get some options, used later
        $options = $this->getOptions();

        // use built-in dependency tracking
        $this->bootstrap('cachemanager');

        // get the bootstrapped resource
        $cachemanager = $this->getResource('cachemanager');

        // do more, with the options and the cachemanager
    }
}
</pre>
<p>Result: The variable <code>$options</code> was merely an empty array and the app would die when trying to access the cachemanager resource.</p>
<p>Apparently since we configured/instantiated all these at the app-level (!), I need to access them through the app-level (!) bootstrap which I can get using <code>$this->getApplication()</code>. So the correct code is:</p>
<pre class="brush:php">
class Front_Bootstrap extends Zend_Application_Module_Bootstrap
{
    protected function _initSomething()
    {
         // get the application-level bootstrap first
         $application = $this->getApplication();

        // get some options, used later
        $options = $application->getOptions();

        // use built-in dependency management
        $application->bootstrap('cachemanager');

        // get the bootstrapped resource
        $cachemanager = $application->getResource('cachemanager');

        // do more, with the options and the cachemanager
    }
}
</pre>
<p>In hindsight, and with all the explicit references I have made to the adjective &#8216;app-level&#8221;, it&#8217;s all pretty obvious. I will note that <code>getApplication()</code> does not return the <code>Zend_Application</code> instance (as the name kind-of implies), but rather the app-level <em>bootstrap</em>. As potentially misleading as the method name may be, I suppose it makes sense since the app-level bootstrap instance is usually more directly useful than the application instance.</p>
<p>With any luck, I&#8217;ll remember it next time. Until then, hope this helps someone else.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2012/04/30/accessing-zend-framework-application-resources-module-bootstraps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework 2: Concepts, Flexibility, Complexity</title>
		<link>http://www.papayasoft.com/2012/04/17/zend-framework-2-concepts-flexibility-complexity/</link>
		<comments>http://www.papayasoft.com/2012/04/17/zend-framework-2-concepts-flexibility-complexity/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 04:42:27 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[zendframework]]></category>
		<category><![CDATA[zf2]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=445</guid>
		<description><![CDATA[As I try to get my own head around the ongoing development of Zend Framework 2 (ZF2) and as I see other beginner/intermediate developers ask similar questions, I though it would be useful &#8211; to me at least &#8211; to articulate some thoughts about how I understand ZF2 and some general concepts that could be [...]]]></description>
			<content:encoded><![CDATA[<p>As I try to get my own head around the ongoing development of <a href="http://framework.zend.com/zf2" title="Zend Framework 2 (ZF2)">Zend Framework 2 (ZF2)</a> and as I see other beginner/intermediate developers <a href="http://stackoverflow.com/q/10182000/131824">ask similar questions</a>, I though it would be useful &#8211; to me at least &#8211; to articulate some thoughts about how I understand ZF2 and some general concepts that could be helpful to understanding the framework. Hopefully, they will be helpful for newbies (and a few not-so-newbies) as well.</p>
<p><strong>tl:dr:</strong> There is a lot of complexity in ZF2 that enables maximum flexibiltiy. I suspect that at some point in the future, much of this complexity can be wrapped in an easy-consumption layer that masks it for those common use-cases that do not require that flexibility.</p>
<p>Generally, I see the following as some of the core ZF2 ideas:</p>
<p>* MVC and dispatch cycle<br />
* Dependency Injection (DI)<br />
* Events<br />
* Modules as first-class citizens</p>
<h2>MVC and the dispatch cycle</h2>
<p>To use ZF2 as more than a component library &#8211; which is a perfectly valid use case &#8211; it is necessary to understand the general notion of MVC and the request dispatch cycle. An HTTP request comes to the web-server; internal objects representing a router, the request, the response, a dispatcher are created; the request is routed to a module/controller/action; data is populated into views which then populate the response; the response is then sent back to the client. Gotta know your MVC.</p>
<h2>Dependency Injection (DI)</h2>
<p>There are many resources on dependency injection &#8211; including a <a href="http://www.papayasoft.com/2011/06/26/dependency-injection/" title="What is dependency injection?">previous blog post</a> &#8211; but the upshot is that if an object (the consumer) needs another object (the dependency) to do its job, then it is more flexible to pass the dependency to the consumer, rather than have the consumer instantiate it itself. This decoupling eases unit testing of the consumer, allowing you to provide a mock dependency that you know functions as expected.</p>
<p>ZF2 has a DI component that is used heavily in the framework code and in many of the current sample apps.</p>
<h2>Events</h2>
<p>Events and Aspect Oriented Programing provide a flexible way to hook external/cross-cutting processing into a line of execution flow. As a request is processed, various events can be broadcast to listeners that perform some processing. </p>
<p>Examples usually cited are logging and caching. Any object that needs to do logging and caching would need to compose objects for that functionality. Since this can result in boilerplate code being repeated all over the place, or in extended class inheritance trees as we attempt to put all this into a base class, we can simply compose a single &#8220;event manager&#8221; that knows how to route events and event-specific information to those listeners who then take action.</p>
<p><a href="http://packages.zendframework.com/docs/latest/manual/en/zend.event-manager.html">ZF2&#8242;s EventManager</a> is also used in the dispatch cycle to expose various stages in that cycle to other components that wish to act at that point.</p>
<p>Much of what you see in the current batch of ZF2 sample apps involves specifying listeners to these events.</p>
<h2>Modules as first-class citizens</h2>
<p>Although ZF1 had a notion of modules, they did not act as &#8220;drop-in&#8221; buckets/bundles of functionality. ZF2 raises the profile of modules so that they can more easily contain their own autoloading, config, routes, views, public web assets, etc. Further, module-specific config can be overriden at the application-level, something which is necessary to make a module truly flexible enough to drop-in, configure, and use.</p>
<h2>Summary</h2>
<p>Much of the complexity that is currently exposed in ZF2 is intended to make app development more flexible. I suspect that as time goes on &#8211; hopefully even before the actual post-beta release &#8211; much of this complexity will be wrappable in an easy set of simple-use-case consumer containers that mask the complexity if you don&#8217;t require all the flexibility.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2012/04/17/zend-framework-2-concepts-flexibility-complexity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom frontends for Zend_Cache</title>
		<link>http://www.papayasoft.com/2011/12/10/custom-frontends-zend-cache/</link>
		<comments>http://www.papayasoft.com/2011/12/10/custom-frontends-zend-cache/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 17:04:16 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[zendframework]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=431</guid>
		<description><![CDATA[As we all know, server-side caching is a useful technique for optimizing the performance of web apps. Whenever some expensive operation is called for &#8211; a db query, a remote web service call, etc &#8211; caching the results of the operation means that the next time you need them, you can get them relatively cheaply [...]]]></description>
			<content:encoded><![CDATA[<p>As we all know, server-side caching is a useful technique for optimizing the performance of web apps. Whenever some expensive operation is called for &#8211; a db query, a remote web service call, etc &#8211; caching the results of the operation means that the next time you need them, you can get them relatively cheaply from the cache.</p>
<h3>Zend_Cache: A basic usage example</h3>
<p>Zend Framework contains a <code>Zend_Cache</code> component that supports a variety of frontends and backends. Typical usage for filesystem-based caching is something like the following:</p>
<pre class="brush:php">

// create the cache object
$frontend = array(
    'lifetime' => 86400, // seconds
    'automatic_serialization' => true,
);
$backend = array(
    'cache_dir' => '/path/to/your/cache',
);
$cache = Zend_Cache::factory('Core', 'File', $frontend, $backend);

// now use the cache object
$cacheId = 'someCacheId';
$data = $cache->load($cacheId);
if (false == $data){
    $data = someExpensiveOperation();
    $cache->save($data, $cacheId);
}
</pre>
<p>In practice, I tend to put the cache creation portion into a factory/container class of some kind, while the usage/consumption is often in a repository or service class. But for clarity, it is shown all in line, as if it were in a controller.</p>
<p>The first time you run through this code, the data will not have been saved in cache (a cache miss, as they say), so you will be forced to incur the cost of the <code>someExpensiveOperation()</code> call. But the next time you run through it &#8211; assuming the cache has not expired beyond its lifetime &#8211; then you will register a cache hit and bypass the expensive operation.</p>
<p>All cool.</p>
<h3>Yeah, but&#8230;</h3>
<p>But there is one thing that has always bugged me about this typical flow: generating the <code>$cacheId</code>. For example, if <code>someExpensiveOperation()</code> is a db call to fetch an article, then the <code>$cacheId</code> will probably employ the id or slug of the article:</p>
<pre class="brush:php">
// $slug is the slug of the article, something like 'my-cool-article'
$cacheId = 'article_byslug_' . str_replace('-', '_', $slug);  // Zend_Cache does not like cache id's with hyphens
</pre>
<p>Generating a cache id strikes me as part of the internal details of the &#8220;caching process&#8221;. As such, it seems to me like the knowledge of how to do that should be embedded inside the caching object itself. It&#8217;s his business to know how to load data from cache, save data to cache, and remove data from cache. Connecting an id to that data should be part of his job. So, why should I have to construct cache id&#8217;s for him?</p>
<p>Even further, why am I seeing cache id&#8217;s at all? Couldn&#8217;t the cache object simply offer me an interface with methods like:</p>
<pre class="brush:php">

public function loadArticlebySlug($slug);
public function saveArticleBySlug($article);
public function removeArticleBySlug($article);
</pre>
<p>Isn&#8217;t there some easy way to make this happen?</p>
<h3>Custom cache frontends to the rescue!</h3>
<p>It turns out that <code>Zend_Cache::factory()</code> actually does allow me to create custom frontends that implement whatever interface I want. I can define my interface:</p>
<pre class="brush:php">
interface Project_Cache_Frontend_ArticleInterface
{
    public function loadArticlebySlug($slug);
    public function saveArticleBySlug($article);
    public function removeArticleBySlug($article);
}
</pre>
<p>Then implement in a class extending <code>Zend_Cache_Core</code>:</p>
<pre class="brush:php">
class Project_Cache_Frontend_Article extends Zend_Cache_Core implements Project_Cache_Frontend_ArticleInterface
{
    public function loadArticlebySlug($slug)
    {
        return $this->load($this->getCacheIdBySlug($article->slug));
    }

    public function saveArticleBySlug($article)
    {
        return $this->save($article, $this->getCacheIdBySlug($article->slug));
    }

    public function removeArticleBySlug($article)
    {
        return $this->remove($this->getCacheIdBySlug($article->slug));
    }

    protected function getCacheIdBySlug($slug)
    {
        return 'article_byslug_' . str_replace('-', '_', $slug);
    }
}
</pre>
<p>Note the protected method <code>getCacheIdBySlug($slug)</code>. All the knowledge of how to create cache id&#8217;s is wrapped up in the cache object. It just exposes a functional interface that describes <em>what</em> you want to do, not <em>how</em> you want it done. </p>
<p>Now, tell the <code>Zend_Cache::factory()</code> method to use my custom frontend:</p>
<pre class="brush:php">
// frontend and backend options as before
$frontend = array(
    'lifetime' => 86400, // seconds
    'automatic_serialization' => true,
);
$backend = array(
    'cache_dir' => '/path/to/your/cache',
);
$cache = Zend_Cache::factory('Project_Cache_Frontend_Article', 'File', $frontend, $backend, true, false, true);
</pre>
<p>Note that we are specifying the complete name of our implementing cache class, as well as three boolean values.</p>
<p>The first boolean value &#8211; <code>true</code> in this case &#8211; tells the factory that we are using a custom frontend.</p>
<p>The second boolean value &#8211; <code>false</code> in this case &#8211; tells the factory that we are not using a custom backend.</p>
<p>The third boolean value &#8211; <code>true</code> in this case &#8211; tells the factory to use autoloading to instantiate the frontend and backend objects.</p>
<p>Fully constructed by the factory, cache usage is cleaner:</p>
<pre class="brush:php">

$data = $cache->loadArticleBySlug($slug);
if (false === $data){
    $data = someExpensiveOperation();
}
</pre>
<p>No cache id&#8217;s, no mixing of concerns.</p>
<p>Maybe it&#8217;s a whole lot of work just to tuck away some cache id generation. But I confess that it feels better to me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2011/12/10/custom-frontends-zend-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The PHP Community. My Community.</title>
		<link>http://www.papayasoft.com/2011/09/09/php-community/</link>
		<comments>http://www.papayasoft.com/2011/09/09/php-community/#comments</comments>
		<pubDate>Fri, 09 Sep 2011 03:42:49 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=424</guid>
		<description><![CDATA[I am a PHP developer. I use PHP for nearly all my server-side development. Much of my learning of design patterns and general best practices and has taken place within a PHP context. I&#8217;ve been doing web development with PHP for a lot of years. During the past three years, I have plunged into new [...]]]></description>
			<content:encoded><![CDATA[<p>I am a PHP developer. I use PHP for nearly all my server-side development. Much of my learning of design patterns and general best practices and has taken place within a PHP context.</p>
<p>I&#8217;ve been doing web development with PHP for a lot of years. During the past three years, I have plunged into new tools and methodologies &#8211; frameworks, MVC, source-control, modeling, layered app architecture, dependency-injection, unit-testing, automated build/deploy, schema migration, API design. It has been  &#8211; and continues to be &#8211; a huge climb. I often feel like a n00b, the new kid in school who just moved from a foreign land and doesn&#8217;t even speak the language, braced to get teased in the playground during recess by the Cool Kids.</p>
<p>But you know what? The Cool Kids &#8211; the more experienced PHP developers &#8211; turned out to be, well, cool.</p>
<p>Whether it&#8217;s an independent developer based on the other side of the world starting his own project on Github, or the founder of a US-based local PHP user group, or an advisory member to several developer conferences, or even the project leads of various popular open-source projects, they have all been uniformly supportive of what I do know and amazingly tolerant of what I don&#8217;t know. These near-total strangers have invited me to local meetups, encouraged me to start my own user-groups and local meetups, have patiently and generously contributed their time to answering my &#8211; often naive &#8211; questions and pointing me to relevant resources.</p>
<p>The expertise that they have shared with me has proven invaluable in improving my skills. Even more notable is their warm humanity, their sharp-witted good humor, and their almost universal encouragement that moves me to ever deeper community engagement.</p>
<p>Upshot: This virtual community, this real community, the PHP community, rocks. It just flat out rocks.</p>
<p>The PHP community. My community.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2011/09/09/php-community/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>What is dependency injection?</title>
		<link>http://www.papayasoft.com/2011/06/26/dependency-injection/</link>
		<comments>http://www.papayasoft.com/2011/06/26/dependency-injection/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 11:36:22 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[unit-testing]]></category>
		<category><![CDATA[dependency-injection]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[zendframework]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=410</guid>
		<description><![CDATA[For quite some time, I have been working on getting my head around best practices for structuring my web applications. One of the strongest messages that has come through is to use dependency injection to facilitate unit testing. As many others have noted, dependency injection is a very simple concept. If one thing (the &#8220;consumer&#8221;) [...]]]></description>
			<content:encoded><![CDATA[<p>For quite some time, I have been working on getting my head around best practices for structuring my web applications. One of the strongest messages that has come through is to use dependency injection to facilitate unit testing.</p>
<p>As many others have noted, dependency injection is a very simple concept. If one thing (the &#8220;consumer&#8221;) depends upon something else (the &#8220;dependency&#8221;) to do its work, then the consumer should be given the dependency. The consumer should depend upon an agreed set of functionality that the dependency performs, but it should not care how the dependency actually gets the job done.</p>
<h3>An easy example</h3>
<p>A radio receives transmissions and plays sounds through its speakers. Nothing special there. But it needs a power source to function. The power source&#8217;s adapter has to fit into the hole on back of the radio. And there has to be some compatibility of voltages and currents and all that electrical magic. The radio is the consumer and the power source is the dependency. You can&#8217;t run the radio without the power source.</p>
<p>Note that, in principle, the power source could be a pack of AA batteries. Or it could be a solar cell. Or it could be a collection of gerbils running on flywheels. As long as it outputs the right voltage and current and the plug fits into the hole, then all is cool. The radio is not concerned by the power source implementation as long it lives up to what we expect a power source to do (i.e., its interface).</p>
<h3>How about some code?</h3>
<p>Using our radio and power source example, we could imagine PHP objects and interfaces as follows:</p>
<pre class="brush: php">
interface PowerSourceInterface
{
	public function getPower($numberOfPowerUnits);
}

class PowerSourceGerbils implements PowerSourceInterface
{
	protected $_gerbils;

	public function __construct($gerbils)
	{
		$this->_gerbils = $gerbils;
	}

	pubic function getPower($numberOfPowerUnits)
	{
		// Make the gerbils run like hell on the flywheel
		// to generate the requested amount of power.
	}
}

class Radio
{
	protected $_powerSource;

	public function __construct(PowerSourceInterface $powerSource)
	{
		$this->_powerSource = $powerSource;
	}

	public function play()
	{
		// Call upon $this->_powerSource->getPower()
		// Feed that power into the various electrical
		// components of the radio and push the sound
		// out through the speakers.
	}
}
</pre>
<p>The idea is that by clearly defining the responsibilities, we can create independent object that fulfill those responsibilities. Even better, by defining interfaces, we can set up a contract for what a particular consumer expects his dependencies to be able to do for him.</p>
<h3>So, who cares? Unit testing cares.</h3>
<p>Suppose you are a company that makes radios. You hire the best radio engineers and work out all the details for what makes a radio great. Maybe you have amazing noise-reduction algorithms that filter out static. Maybe your radios have balance and equalizer controls to allow the user to tweak the sound he gets out of your box. Maybe your radios are super efficient so that they pull less power from the power source, allowing them to play longer before recharge. Or maybe you simply put them in colorful plastic shells featuring photos of some random pop star.</p>
<p>The point is that your expertise is in the areas highlighted above. You make no representation to be experts in power generation; you are a power <em>consumer</em>. The quality of <em>your</em> work can only be fairly judged when the power source functions properly. Hey, man, if the power source tanks, then all bets are off, right? </p>
<p>So as part of your manufacturing process, you do a whole bunch of unit-testing on your radios using a &#8220;mock&#8221; power source, a power source that definitely functions correctly. This approach &#8211; explicitly defining and passing dependencies, combined with supplying mock dependencies during unit testing &#8211; clearly defines responsibilities and allows you to focus on fulfilling yours without worrying that the problem lies in someone else&#8217;s area of responsibility.</p>
<h3>What&#8217;s the downside?</h3>
<p>Well, creating objects is now a bit of a pain the neck. Consider what is required now just to play a radio.</p>
<pre class="brush: php">
$gerbils = new GerbilCollection();  // guess we need a Gerbil class and a GerbilCollection class, too
$powerSource = new PowerSourceGerbils($gerbils);
$radio = new Radio($powerSource);
$radio->play();
</pre>
<p>So, every time I want to play a radio, I need to construct a power source (which might have its own dependencies, like the gerbils in this case), feed that power source into the radio, and then hit the play button.</p>
<p>I gotta do all these steps just to play a freaking radio? Can&#8217;t I do the radio setup once &#8211; create and plug in the power source &#8211; and then when I want to listen to some music, all I have to do is hit play?</p>
<p>I will address this in the next post: Poor Man&#8217;s Dependency Injection using Zend Framework.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2011/06/26/dependency-injection/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Unit testing for placeholder-based view-helpers in Zend Framework</title>
		<link>http://www.papayasoft.com/2011/03/12/unit-testing-zend-framework-placeholder-view-helpers/</link>
		<comments>http://www.papayasoft.com/2011/03/12/unit-testing-zend-framework-placeholder-view-helpers/#comments</comments>
		<pubDate>Sat, 12 Mar 2011 16:22:08 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[unit-testing]]></category>
		<category><![CDATA[zendframework]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=371</guid>
		<description><![CDATA[Just got bitten by an interesting little issue. I have a Zend Framework view-helper that I use to add a CSS class to an HTML &#60;body&#62; tag. Usage in a view-script is: $this->bodyTag()->addClass('someclass'); Then in a layout, I&#8217;d output it using: &#60;?= $this->bodyTag() ?&#62; The class itself is very simple: /** * A body tag [...]]]></description>
			<content:encoded><![CDATA[<p>Just got bitten by an interesting little issue.</p>
<p>I have a <a href="http://framework.zend.com/">Zend Framework</a> view-helper that I use to add a CSS class to an HTML <code>&lt;body&gt;</code> tag. Usage in a view-script is:</p>
<pre class="brush:php">
$this->bodyTag()->addClass('someclass');
</pre>
<p>Then in a layout, I&#8217;d output it using:</p>
<pre class="brush:php">
&lt;?= $this->bodyTag() ?&gt;
</pre>
<p>The class itself is very simple:</p>
<pre class="brush:php">

/**
 * A body tag
 *
 * @author David Weinraub &lt;david@papayasoft.com&gt;
 */
class PapayaSoft_Zend_View_Helper_BodyTag extends Zend_View_Helper_Placeholder_Container_Standalone
{
    public function bodyTag()
    {
        return $this;
    }

    public function toString()
    {
        $tag = array();
        $tag[] = '&lt;body';

        $storage = $this->getContainer();

        if (count($storage) > 0){
            $classes = array();
            foreach ($storage as $class){
                $classes[] = $class;
            }
            $tag[] = sprintf(' class="%s"', implode(' ', $classes));
        }
        $tag[] = '&gt;';
        return implode('', $tag);
    }

    public function addClass($class)
    {
        $this->getContainer()->append($class);
        return $this;
    }
}
</pre>
<p>I&#8217;ve begun moving this kind of stuff out into my own library, which I will manage in its own project under source control. I can then import it into multiple projects, just as I would with the libs for <a href="http://framework.zend.com/">Zend</a> or <a href="http://www.doctrine-project.org/">Doctrine</a> or <a href="http://htmlpurifier.org/">HTML Purifier</a>. </p>
<p>Consequently, it&#8217;s now time &#8211; actually long past-due &#8211; to really get into the discipline of unit-testing. A simple class like this seems a decent place to start.</p>
<p>Unit-tests for the BodyTag class looked something like this:</p>
<pre class="brush:php">

/**
 * Test BodyTag class
 *
 * @group Zend_View_Helper
 * @author David Weinraub &lt;david@papayasoft.com&gt;
 */
class PapayaSoft_Zend_View_Helper_BodyTagTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var PapayaSoft_Zend_View_Helper_BodyTag
     */
    private $_bodyTag;

    public function setUp()
    {
        $this->_bodyTag = new PapayaSoft_Zend_View_Helper_BodyTag();
    }

    public function tearDown()
    {
        unset($this->_bodyTag);
    }

    public function testRenderOnNoAddedClasses()
    {
        $this->assertEquals('&lt;body&gt;', (string) $this->_bodyTag);
    }

    public function testRenderOnSingleAddedClass()
    {
        $this->_bodyTag->addClass('myclass');
        $this->assertEquals('&lt;body class="myclass"&gt;', (string) $this->_bodyTag);
    }

    public function testRenderOnMultipleAddedClasses()
    {
        $this->_bodyTag = new PapayaSoft_Zend_View_Helper_BodyTag();
        $this->_bodyTag->addClass('someclass')->addClass('anotherclass');
        $this->assertEquals('&lt;body class="someclass anotherclass"&lt;', (string) $this->_bodyTag);
    }
}
</pre>
<p>Pretty straightforward. Or so I thought.</p>
<p>The last test failed, reporting the following:</p>
<pre class="brush:php">
BodyTagTest::testRenderOnMultipleAddedClasses()
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-&lt;body class="someclass anotherclass"&gt;
+&lt;body class="myclass someclass anotherclass"&gt;
</pre>
<div style="text-align:left;">
It seemed as if result of running the penultimate method <code>testRenderOnSingleAddedClass()</code> was still in effect when <code>testRenderOnMultipleAddedClasses()</code> started. When the <code>testRenderOnSingleAddedClass()</code> method is removed, the <code>testRenderOnMultipleAddedClasses()</code> passes.
</div>
<p>What&#8217;s going on here? The whole point of <code>tearDown()</code> and <code>setUp()</code> is to reset the test environment to a clean state, in this case by unsetting and re-instantiating the <code>$_bodyTag</code> member variable. </p>
<p>Well, the whole key here turns out to be state of the system. It&#8217;s not sufficient to simply reset the object in the member variable if it has made other changes to the state of the system. Sort of like selling the cow that crapped in your living room, but forgetting to clean up the mess he made. And that&#8217;s actually what appears to be happening.</p>
<p>The framework&#8217;s own unit test for <code>Zend_View_Helper_HeadTitle</code>, another <code>Zend_View_Helper_Placeholder_Container_Standalone</code>-extended class, offers some hint of this. The <code>setUp()</code> method is as follows:</p>
<pre class="brush:php">
    /**
     * Sets up the fixture, for example, open a network connection.
     * This method is called before a test is executed.
     *
     * @return void
     */
    public function setUp()
    {
        $regKey = Zend_View_Helper_Placeholder_Registry::REGISTRY_KEY;
        if (Zend_Registry::isRegistered($regKey)) {
            $registry = Zend_Registry::getInstance();
            unset($registry[$regKey]);
        }
        $this->basePath = dirname(__FILE__) . '/_files/modules';
        $this->helper = new Zend_View_Helper_HeadTitle();
    }
</pre>
<p>So there is some </code>Zend_Registry</code> stuff in there that needs to be cleared, as well. Adding the registry-clearing code from the ZF unit-test into my own solved the problem.</p>
<p>Live and learn.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2011/03/12/unit-testing-zend-framework-placeholder-view-helpers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CRISP-y goodness: tracking Phuket internet speeds</title>
		<link>http://www.papayasoft.com/2010/12/27/crispy-goodness-2/</link>
		<comments>http://www.papayasoft.com/2010/12/27/crispy-goodness-2/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 07:41:29 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[zendframework]]></category>
		<category><![CDATA[crisp]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[phuket]]></category>
		<category><![CDATA[woody]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=359</guid>
		<description><![CDATA[I am pleased to report that we have launched the new version of CRISP &#8211; Customers Reporting Internet Speeds in Phuket. For some years, well-known computer columnist and baker Woody Leonhard (see AskWoody.com for his opinions on Windows patches or his columns in the Windows Secrets Newsletter, or his various Windows for Dummies books, not [...]]]></description>
			<content:encoded><![CDATA[<p>I am pleased to report that we have launched the new version of <a href="http://ww.khunwoody.com/phuket-internet-speed/">CRISP &#8211; Customers Reporting Internet Speeds in Phuket</a>.</p>
<p>For some years, well-known computer columnist and baker <a href="http://twitter.com/phuketpc">Woody Leonhard</a> (see AskWoody.com for his opinions on <a href="http://www.askwoody.com/">Windows patches</a> or his columns in the <a href="http://windowssecrets.com/search?q=woody">Windows Secrets Newsletter</a>, or his various <a href="http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dstripbooks&#038;field-keywords=windows+dummies+woody&#038;x=0&#038;y=0">Windows for Dummies books</a>, not to mention his <a href="http://thephuketbakery.com/">bakery business</a> and his <a href="http://www.phuketinternetcafe.com/">Phuket Sandwich Shoppes</a>) has led a group of Phuket internet users in running speed tests on their internet connections and storing this data in an app developed and hosted by <a href="http://www.psp-online.com/">Henry Habermacher</a>. The data was freely available as a CSV download to anyone who wanted to perform their own analysis on it.</p>
<p>Woody&#8217;s prime motivations were to provide Phuket internet users with real usage data on which to base their ISP choices and to clearly demonstrate the significant discrepancy between speeds advertised by ISP&#8217;s in Phuket and those that are actually delivered.</p>
<p>As of this writing, the db has over 15,000 speed reports dating back to 2008.</p>
<p>Henry was unable to host it going forward, so we needed to move it to a new home. But rather than simply migrate, we decided to do a rewrite in PHP and I got the call. Using a design by <a href="http://tessellations.org/contact.htm">Seth Bareiss</a>, my re-implementation is built on <a href="http://framework.zend.com/">Zend Framework</a> and the <a href=""http://www.doctrine-project.org/">Doctrine 1</a> ORM. Relative to the previous version, it features some enhanced searching and user management, including registration and profile management.</p>
<p>If you are a Phuket-based internet user, come on over, <a href="http://www.khunwoody.com/phuket-internet-speed/user/register">register</a>, and start contributing to the tracking effort.</p>
<p><a href="http://www.khunwoody.com/phuket-internet-speed/">http://www.khunwoody.com/phuket-internet-speed/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2010/12/27/crispy-goodness-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Greeting</title>
		<link>http://www.papayasoft.com/2010/12/25/greeting/</link>
		<comments>http://www.papayasoft.com/2010/12/25/greeting/#comments</comments>
		<pubDate>Sat, 25 Dec 2010 05:50:21 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Dropcloth]]></category>
		<category><![CDATA[christmas]]></category>
		<category><![CDATA[greeting]]></category>
		<category><![CDATA[xmas]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=352</guid>
		<description><![CDATA[$papayasoft->wishesYou(array( new Christmas('merry'), new Year(array('happy', 'healthy', 'prosperous')), )); $this->assert($papayasoft->isGeek());]]></description>
			<content:encoded><![CDATA[<pre class="brush: php">

$papayasoft->wishesYou(array(
	new Christmas('merry'),
	new Year(array('happy', 'healthy', 'prosperous')),
));
$this->assert($papayasoft->isGeek());
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2010/12/25/greeting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework default routing for hyphenated and camelCase URL&#8217;s</title>
		<link>http://www.papayasoft.com/2010/12/22/zend-framework-routing-hyphen-camelcase/</link>
		<comments>http://www.papayasoft.com/2010/12/22/zend-framework-routing-hyphen-camelcase/#comments</comments>
		<pubDate>Wed, 22 Dec 2010 10:14:18 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[zendframework]]></category>
		<category><![CDATA[routing]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=347</guid>
		<description><![CDATA[Using the default routing in Zend Framework (v1.x), I always forget how certain URL patterns map to action and view-script names. So just a quick post, mostly for myself, to record them here. URL: mycontroller/test-me Controller: mycontroller Action: testMe Script: test-me.phtml URL: mycontroller/testMe Controller: mycontroller Action: testme Script: test-me.phtml That&#8217;s it!]]></description>
			<content:encoded><![CDATA[<p>Using the default routing in Zend Framework (v1.x), I always forget how certain URL patterns map to action and view-script names. So just a quick post, mostly for myself, to record them here.</p>
<p><strong>URL:</strong> mycontroller/test-me<br />
<strong>Controller</strong>: mycontroller<br />
<strong>Action:</strong> testMe<br />
<strong>Script:</strong> test-me.phtml</p>
<p><strong>URL:</strong> mycontroller/testMe<br />
<strong>Controller:</strong> mycontroller<br />
<strong>Action:</strong> testme<br />
<strong>Script:</strong> test-me.phtml</p>
<p>That&#8217;s it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2010/12/22/zend-framework-routing-hyphen-camelcase/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Naming conventions for database tables and fields</title>
		<link>http://www.papayasoft.com/2010/12/09/database-naming-convention/</link>
		<comments>http://www.papayasoft.com/2010/12/09/database-naming-convention/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 08:00:38 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.papayasoft.com/?p=335</guid>
		<description><![CDATA[@JeremyKendall recently asked a great question on Twitter: Do you have a DB naming convention? camelCase? under_scores? Singular or plural table names? I can never settle on anything. He got some great answers. Since I will certainly need to reference these opinions at some later date &#8211; and Twitter will not keep the history forever [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/JeremyKendall">@JeremyKendall</a> recently asked a <a href="http://twitter.com/#!/JeremyKendall/status/12619603062554624">great question</a> on Twitter:</p>
<blockquote><p>
Do you have a DB naming convention? camelCase? under_scores? Singular or plural table names? I can never settle on anything.
</p></blockquote>
<p>He got some great answers. Since I will certainly need to reference these opinions at some later date &#8211; and Twitter will not keep the history forever &#8211; I am recording them here.</p>
<p><a href="http://twitter.com/konrness">@konrness</a><br />
I find it&#8217;s easier to follow my PHP code&#8217;s naming convention, so: camelCase for table names and columns. Under_score for DBs. Oh yeah, I usually do plural table names.</p>
<p><a href="http://twitter.com/stuardo_str">@stuardo_str</a><br />
namespaced_under_scored</p>
<p><a href="http://twitter.com/cancehgarcia">@cancehgarcia</a><br />
i once read that &#8220;best practice&#8221; is singular and underscores. but as long as you&#8217;re consistent in the db, you should be good.</p>
<p><a href="http://twitter.com/cryptographite">@cryptographite</a><br />
CamelCase (ucfirst) for tables, and pre_desc for columns. User.u_id, UserProperties.up_value&#8230; It&#8217;s not perfect but it works</p>
<p><a href="http://twitter.com/calevans">@calevans</a><br />
single table names, camleCase attributes and PK is always id</p>
<p><a href="http://twitter.com/maphpia">@maphpia</a><br />
namespaced_underscore_name, singular, and &#8216;id&#8217; as PK</p>
<p><a href="http://twitter.com/guice">@guice</a><br />
for us; id is always tablename_id to avoid name conflicts between joins. We use underscore (oracle). Singular names.</p>
<p><a href="http://twitter.com/akrabat">@akrabat</a><br />
Plural table names; lowercase, underscore separated field names; PK is always id.</p>
<p><a href="http://twitter.com/avalanche123">@avalanche123</a><br />
lowercase underscore plural table names, id is the PK, &lt;singular table name&gt;_id is the FK to table name</p>
<p><a href="http://twitter.com/h">@h</a> (which is an awesome Twitter handle)<br />
Singular Table names, first char upper case. Allows you to create models that match exactly.</p>
<p><a href="http://twitter.com/tommygeorge">@tommygeorge</a><br />
Depends on the project, but I hate camelcase, and if I&#8217;m doing models/objects, I generally do plurals for table names.</p>
<p><a href="http://twitter.com/brodrigu">@brodrigu</a><br />
plural under_scores ftw!</p>
<p>I actually <a href="http://twitter.com/#!/papayasoft/statuses/12714163465887744">chimed in</a> with my own support for @avalanche123&#8242;s suggestion: lowercase underscore plural table names, id is the PK, &lt;singular table name&gt;_id is the FK to table name. Semantically, I find this compelling since you end up with SQL queries of like &#8220;SELECT * FROM users&#8221; which reads better to my eye than &#8220;SELECT * FROM user&#8221;. </p>
<p>The only downside to this is that dealing with irregular plurals can sometimes be a pain. Consider a table containing properties. As noted above, I prefer the semantics that follow from calling that table &#8220;properties&#8221;. But a convention for a FK into that table &#8220;<singular_table_name>_id&#8221; would yield a field named &#8220;property_id&#8221;. The disconnect between the singular and plural can sometimes be problematic. Sure, there are Inflector classes (<a href="http://www.phpclasses.org/browse/file/12343.html">like this one</a>) that know enough about English pluralization rules and their exceptions to do the mapping, but it&#8217;s one more hassle. So there are times when I bite the bullet, abandon the superior semantics, and simply hold my nose and go with singular table names.</p>
<p>What are your preferences and rationale?</p>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.papayasoft.com/2010/12/09/database-naming-convention/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

