<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"> <channel><title>Malt Blue</title> <link>http://www.maltblue.com</link> <description>Zend Framework Tutorials Taking You from Beginner to Advanced with Articles, Tips, Tricks, Interviews, Podcasts, Reviews and more.</description> <lastBuildDate>Fri, 14 Jun 2013 19:27:01 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.5</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/MaltBlue" /><feedburner:info uri="maltblue" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>Zend Framework Tutorials Taking You from Beginner to Advanced with Articles, Tips, Tricks, Interviews, Podcasts, Reviews and more.</itunes:subtitle><item><title>Using ZFTool for Basic Project Management</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/vJsY37tublw/zftool-for-basic-project-management</link> <comments>http://www.maltblue.com/tutorial/zftool-for-basic-project-management#comments</comments> <pubDate>Fri, 14 Jun 2013 16:00:23 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Beginner]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[tooling]]></category> <category><![CDATA[Zend Framework]]></category> <category><![CDATA[zftool]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12277</guid> <description><![CDATA[In today's tutorial, we go through the key options in ZFTool, the tooling support available in Zend Framework 2. We install it, create a basic ZF2 application and more. ]]></description> <content:encoded><![CDATA[<p><strong>Level:</strong> Beginner</p><p><strong>Duration:</strong> 20 mins</p><h2>Introduction</h2><p>Welcome to another tutorial. Today, I will be giving you a walk through of zftool, which provides basic tooling support in Zend Framework 2. If you&#8217;re new to Zend Framework, or have been <a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection">reading the introductory series</a> here, it can come in quite handy.</p><p>But unlike other frameworks, such as <strong>Yii</strong> (<a
href="http://www.yiiframework.com/doc/guide/1.1/en/quickstart.first-app" title="The Yiic Tool in Yii Framework">through yiic</a>) and <strong>Symfony</strong> (<a
href="http://symfony.com/doc/current/components/console/introduction.html" title="The Symfony Console Component">via the Command Line tool</a>), the tooling support in Zend Framework 2 is rather light on.</p><p>These respective tools provide rather robust support for automatically generating models from database connections, checking logs and a host of other much required functionality.</p><p>I understand from some tweets with <a
href="http://www.twitter.com/ezimuel">Enrico Zimuel</a> new additions are planned for zftool. But for right now, Zend Framework is definitely the junior. However, that aside, I like to take the adage of a glass half full and see zftool as a good start. Today we&#8217;re going to use it to carry out the following tasks:</p><ol><li>Create a basic ZF2 project</li><li>Create several modules</li><li>Creating an autoloader classmap</li><li>Checking if there are any issues</li></ol><p>By the end of today&#8217;s tutorial, you will have a good understanding of how to get started with it and to be able to use it in your projects. Firstly, let&#8217;s install zftool and get started.</p><div
class="author-box"> <strong>Note for Windows Users</strong></p><p>This tutorial is run under Ubuntu Linux. However, with only minor changes, you can run it in your version of Windows as well.</p></div><h2>Installation</h2><p>There are a number of ways in which zftool can be installed, including using Composer and <a
href="https://packages.zendframework.com/zftool.phar" title="Zend Framework Tool (ZFTool) Phar file">downloading the Phar tool</a>.</p><p>During the research for this article, I tried to <a
href="http://framework.zend.com/manual/2.1/en/modules/zendtool.introduction.html#installation-using-composer">install it via Composer</a>, but continuously met with permission related errors. As a result, I&#8217;ve chosen to focus on the Phar tool approach, which works, almost, seamlessly.</p><p>If you&#8217;d like to go down the Composer route, run the following command in your Terminal or console and you&#8217;ll have it available.</p><pre>$ composer require zendframework/zftool:dev-master</pre><p>Otherwise, download <a
href="http://...">the phar file</a>. Once it&#8217;s downloaded, run the following commands. These make it accessible universally on your system:</p><pre>sudo cp -v zftool.phar /bin/
cd /bin/
sudo ln -s zftool.phar zftool
sudo chmod +x zftool.phar
</pre><p>If you&#8217;re not familiar with the Linux command line, what we&#8217;ve done here is to copy zftool.phar to one of the directories automatically in a users PATH.</p><p>Then we&#8217;ve created a symlink to it, giving it a simpler name and finally set the executable bit on it &#8211; <em>now it&#8217;s ready to run</em>.</p><h2>Running the Phar Tool</h2><p>Now that we have the Phar file available, let&#8217;s have a look at the options available. Running the following command will display a help screen, showing all of the options supported:</p><pre>zftool.phar
</pre><p>It will result in output similar to that below:</p><pre>--------------------------------------------------------------------------------
ZFTool
--------------------------------------------------------------------------------
Basic information:
  zftool.phar modules [list]         show loaded modules
  zftool.phar version | --version    display current Zend Framework version
Diagnostics
  zftool.phar diag [options] [module name]    run diagnostics
  [module name]    (Optional) name of module to test
  -v --verbose     Display detailed information.
  -b --break       Stop testing on first failure
  -q --quiet       Do not display any output unless an error occurs.
  --debug          Display raw debug info from tests.
Application configuration:
  zftool.phar config [list]                list all configuration options
  zftool.phar config get &lt;name&gt;            display a single config value, i.e. &quot;config get db.host&quot;
  zftool.phar config set &lt;name&gt; &lt;value&gt;    set a single config value (use only to change scalar values)
Project creation:
  zftool.phar create project &lt;path&gt;    create a skeleton application
  &lt;path&gt;    The path of the project to be created
Module creation:
  zftool.phar create module &lt;name&gt; [&lt;path&gt;]    create a module
  &lt;name&gt;    The name of the module to be created
  &lt;path&gt;    The root path of a ZF2 application where to create the module
Classmap generator:
  zftool.phar classmap generate &lt;directory&gt; &lt;classmap file&gt; [--append|-a] [--overwrite|-w]
  &lt;directory&gt;         The directory to scan for <acronym title="Pre-Hypertext Processing">PHP</acronym> classes (use &quot;.&quot; to use current directory)
  &lt;classmap file&gt;     File name for generated class map file  or - for standard output.If not supplied, defaults to
                      autoload_classmap.php inside &lt;directory&gt;.
  --append | -a       Append to classmap file if it exists
  --overwrite | -w    Whether or not to overwrite existing classmap file
Zend Framework 2 installation:
  zftool.phar install zf &lt;path&gt; [&lt;version&gt;]
  &lt;path&gt;       The directory where to install the ZF2 library
  &lt;version&gt;    The version to install, if not specified uses the last available
</pre><h2>Creating a Project</h2><p>Ok, with the tool ready to go, let&#8217;s set about using some of it&#8217;s functionality to creating and managing a Zend Framework 2 project, as outlined above.</p><h2>Create the Project</h2><p>Firstly, we&#8217;ll create a raw project, called &#8216;simple project&#8217;. To do so, run the following command:</p><pre>$ php zftool.phar create project ./simpleproject</pre><p>This will create the core project files in a directory in the current directory, called &#8216;simpleproject&#8217;. It will give you output similar to that below:</p><pre>ZF2 skeleton application installed in ./simpleproject.
In order to execute the skeleton application you need to install the ZF2 library.
Execute: &quot;composer.phar install&quot; in ./simpleproject
For more info in ./simpleproject/README.md
</pre><p>Assuming there were no permission issues, the project directory should look as follows:</p><pre>$ ls -l ./simpleproject/
-rw-rw-r-- 1 maltblue maltblue    342 Jun 12 06:34 composer.json
-rwxr-xr-x 1 maltblue maltblue 709565 Jun 12 06:34 composer.phar
drwxrwxr-x 3 maltblue maltblue   4096 Jun 12 06:34 config
drwxrwxr-x 3 maltblue maltblue   4096 Jun 12 06:34 data
-rw-rw-r-- 1 maltblue maltblue   1807 Jun 12 06:34 init_autoloader.php
-rw-rw-r-- 1 maltblue maltblue   1548 Jun 12 06:34 LICENSE.txt
drwxrwxr-x 3 maltblue maltblue   4096 Jun 12 06:34 module
drwxrwxr-x 5 maltblue maltblue   4096 Jun 12 06:34 public
-rw-rw-r-- 1 maltblue maltblue   1759 Jun 12 06:34 README.md
drwxrwxr-x 3 maltblue maltblue   4096 Jun 12 06:34 vendor
</pre><h2>The Generated composer.json File</h2><p>Looking in the project directory, we see <a
href="http://getcomposer.org">a new composer.json file</a>, which has the basic configuration and requirements for a Zend Framework 2 project. If you&#8217;d like to go further, feel free to alter it as suits your needs, running <strong>composer update</strong> afterwards.</p><pre>{
    &quot;name&quot;: &quot;zendframework/skeleton-application&quot;,
    &quot;description&quot;: &quot;Skeleton Application for ZF2&quot;,
    &quot;license&quot;: &quot;BSD-3-Clause&quot;,
    &quot;keywords&quot;: [
        &quot;framework&quot;,
        &quot;zf2&quot;
    ],
    &quot;homepage&quot;: &quot;http://framework.zend.com/&quot;,
    &quot;require&quot;: {
        &quot;php&quot;: &quot;&gt;=5.3.3&quot;,
        &quot;zendframework/zendframework&quot;: &quot;&gt;2.2.0rc1&quot;
    }
}
</pre><h2>Installing Zend Framework 2 in the Project (With Composer)</h2><p>With the basic files in place, unless you have the Zend Framework libraries on your path, the application won&#8217;t run. So, in the project directory, run <strong>composer.phar install</strong> to bring in the required libraries and dependencies.</p><p>The output will look similar to that below. I&#8217;ve trimmed it for sakes of readability.</p><pre>$ composer.phar install
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing zendframework/zendframework (2.2.0)
    Downloading: 100%
Writing lock file
Generating autoload files
</pre><h2>Creating a Module</h2><p>Now we&#8217;ve got the base project and dependencies, let&#8217;s create a module. We&#8217;ll call it &quot;application&quot;.</p><p><strong>NB:</strong> I believe case is not important; so <strong>Application = application</strong>.</p><p>To create it, run the following command, from your project directory:</p><pre>$ zftool.phar create module application</p></pre><p>Running it, however, returns output listing a series of mkdir errors. I believe this came about as the Application module was already there. If so, it would be helpful to print out a simple message indicating this, instead of attempting to proceed with creating an existing module.</p><h2>Creating Another Module</h2><p>Ok, now let&#8217;s create a module which doesn&#8217;t already exist; we&#8217;ll call it <strong>Generic</strong>. As before, we create the module via the command below:</p><pre>zftool.phar create module Generic</pre><p>You should see output similar to that below, indicating there were no problems.</p><pre>The module Generic has been created</pre><p>Looking in the Generic module directory, we see the following structure:</p><pre>$ ls -l module/Generic/
total 16
drwxrwxr-x 2 maltblue maltblue 4096 Jun 12 06:47 config
-rw-rw-r-- 1 maltblue maltblue  437 Jun 12 06:47 Module.php
drwxrwxr-x 3 maltblue maltblue 4096 Jun 12 06:47 src
drwxrwxr-x 2 maltblue maltblue 4096 Jun 12 06:47 view
</pre><p>Under config is a module.config.php file. So, we now have the basic structure of a ZF2 module.</p><h2>Viewing a List of Modules</h2><p>But what if we want to see the list of modules? Well, here&#8217;s where I hit an issue. I believe the following command will show us that list.</p><pre>$ php zftool.phar modules</pre><p>But no matter what I tried, it always resulted in the following error:</p><pre>No modules installed. Are you in the root folder of a ZF2 application?
</pre><p>At this stage, I&#8217;m not sure if it&#8217;s a bug or a user (me) problem. However, as I get more information, I&#8217;ll update the post about this issue.</p><h2> Classmap Generation</h2><p>Ok, we&#8217;re just about done. If you&#8217;re familiar with Zend Framework 2, you&#8217;ll know that performance can be increased through a classmap file.</p><p>A class map file stores a map of files which the application may require, saving it from performing a file location resolution. Effectively, it&#8217;s a class file location cache.</p><p>Let&#8217;s assume we have a series of classes in the module directory. Let&#8217;s create a classmap file for it. To do so, we run the following command:</p><pre>$ zftool classmap generate module/ autoad<em>classmap.php</pre><p>This looks for all class files in the module directory and then writes it out to autoad</em>classmap.php in the current directory. It will have output similar to that below:</p><pre>Creating classmap file for library in /home/parallels/zftool/vendor/simpleproject/module
Scanning for files containing <acronym title="Pre-Hypertext Processing">PHP</acronym> classes .... DONE
Found 4 <acronym title="Pre-Hypertext Processing">PHP</acronym> classes
Creating classmap code ... DONE
Writing classmap to autoload_classmap.php...  DONE
Wrote classmap to /home/parallels/zftool/vendor/simpleproject/autoload_classmap.php
</pre><h2>The Generated Classmap File</h2><p>If you&#8217;ve not seen a classmap file before, here&#8217;s what the one we just created looks like (formatted for better readability):</p><pre>
    $ cat autoload_classmap.php
    &lt;?php
    // Generated by Zend Framework 2
    return array(
        'Generic\Module' =&gt; <strong>DIR</strong> . '/module/Generic/Module.php',
        'Application\Controller\IndexController' =&gt; <strong>DIR</strong> .
'/module/Application/src/Application/Controller/IndexController.php',
        'Application\Module' =&gt; <strong>DIR</strong> . '/module/Application/Module.php',
        'Users\Module' =&gt; <strong>DIR</strong> . '/module/Users/Module.php',</p>
</pre><h2>Running Diagnostics</h2><p>Now on to the last command we&#8217;re going to run, module diagnostics. I&#8217;m going to run diagnostics on the new, Generic, module we&#8217;ve created in this tutorial. From the project root, run the following command:</p><pre>$ zftool diag --debug Generic</pre><p>This will run diagnostics, showing debug information. In this case, just re-iterating the running version of <acronym
title="Pre-Hypertext Processing">PHP</acronym>.</p><pre>Starting diagnostics:
OK   ZF: <acronym title="Pre-Hypertext Processing">PHP</acronym> Version: Current <acronym title="Pre-Hypertext Processing">PHP</acronym> version is 5.4.6-1ubuntu1.2
--------------------------------------------------------------------
'5.4.6-1ubuntu1.2'
------------------------------------------------------------------------
OK (1 diagnostic tests)
</pre><h3>Verbose Information</h3><p>Running it again, with the verbose flag set, show&#8217;s approximately the same information, just less detailed. We can see here there were no issues with the module. So there was nothing to report.</p><pre>
$ php ../zftool.phar diag -v Application
Starting diagnostics:
OK   ZF: <acronym title="Pre-Hypertext Processing">PHP</acronym> Version: Current <acronym title="Pre-Hypertext Processing">PHP</acronym> version is 5.4.6-1ubuntu1.2</p>
OK (1 diagnostic tests)
</pre><p>I must admit I&#8217;m not quite sure of the intent of the diagnostic tool. I&#8217;ve renamed Module.php in Generic, renamed the Generic module directory, yet still the tool reports everything is ok.</p><p>I&#8217;ll be doing so more research into this and updating the article with what is found.</p><h2>Conclusion</h2><p>And this brings us to the end of our walkthrough of zftool in Zend Framework 2.  Now that we&#8217;ve finished the walk through, I hope you now have a good understanding of how to use it in your projects, to alleviate some of the manual work required in setting them up as well as creating modules.</p><p>I&#8217;m looking forward to it having a larger array of features, as time goes on. But for now, unfortunately, zftool is rather limited.</p><p>If you&#8217;d like to contribute to the project and help get the features reader sooner, clone a copy of the code and get involved. I&#8217;m sure your contribution will be well received.</p><p>What do you think of zftool? Good enough to use in your projects? Do you have home-made tools that already do what it provides (and more)? If so, share your thoughts in the comments.</p><h2>Related Links</h2><ul><li><a
href="http://getcomposer.org" title="Php Composer Project">Composer</a></li><li><a
href="https://github.com/zendframework/ZFTool" title="Utility module for maintaining modular Zend Framework 2 applications.">zftool on Github</a></li><li><a
href="http://www.yiiframework.com/doc/guide/1.1/en/quickstart.first-app" title="Creating Your First Yii Application">Yii tools</a></li><li><a
href="http://symfony.com/doc/current/components/console/introduction.html" title="The Symfony Console Component">Symfony tools</a></li></ul><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-2561" ><a
href="http://www.maltblue.com/php/zend-form-multiple-submit-buttons" class="wp_rp_thumbnail"><img
width="84" height="150" src="http://www.maltblue.com/wp-content/uploads/2011/09/simple-decision-tree.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form &#8211; Multiple Submit Buttons" title="" /></a><a
href="http://www.maltblue.com/php/zend-form-multiple-submit-buttons" class="wp_rp_title">Zend Form &#8211; Multiple Submit Buttons</a></li><li
data-position="1" data-poid="in-5351" ><a
href="http://www.maltblue.com/zend-framework/rename-uploaded-files-with-zend-framework" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Rename uploaded files with Zend Framework" title="" /></a><a
href="http://www.maltblue.com/zend-framework/rename-uploaded-files-with-zend-framework" class="wp_rp_title">Rename uploaded files with Zend Framework</a></li><li
data-position="2" data-poid="in-12250" ><a
href="http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 &#8211; The New HTML5 Form Fields" title="" /></a><a
href="http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction" class="wp_rp_title">Zend Framework 2 &#8211; The New HTML5 Form Fields</a></li><li
data-position="3" data-poid="in-1247" ><a
href="http://www.maltblue.com/zend-framework/extending-zend-auth-a-zend-config-adapter" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Extending Zend Auth &#8211; A Zend Config Adapter" title="" /></a><a
href="http://www.maltblue.com/zend-framework/extending-zend-auth-a-zend-config-adapter" class="wp_rp_title">Extending Zend Auth &#8211; A Zend Config Adapter</a></li><li
data-position="4" data-poid="in-12119" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/zf2-eventmanager-feature-image-resized-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 ServiceManager &#8211; Web Application Development Simplified" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" class="wp_rp_title">Zend Framework 2 ServiceManager &#8211; Web Application Development Simplified</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=vJsY37tublw:h5ix5QmikOM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=vJsY37tublw:h5ix5QmikOM:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=vJsY37tublw:h5ix5QmikOM:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=vJsY37tublw:h5ix5QmikOM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=vJsY37tublw:h5ix5QmikOM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=vJsY37tublw:h5ix5QmikOM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=vJsY37tublw:h5ix5QmikOM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=vJsY37tublw:h5ix5QmikOM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=vJsY37tublw:h5ix5QmikOM:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=vJsY37tublw:h5ix5QmikOM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=vJsY37tublw:h5ix5QmikOM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/vJsY37tublw" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/tutorial/zftool-for-basic-project-management/feed</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://www.maltblue.com/tutorial/zftool-for-basic-project-management</feedburner:origLink></item> <item><title>Zend Framework 2 – The New HTML5 Form Fields</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/_R_7MARwmhU/zf2-html5-form-field-introduction</link> <comments>http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction#comments</comments> <pubDate>Wed, 29 May 2013 14:00:44 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Beginner]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[html5]]></category> <category><![CDATA[Zend Form]]></category> <category><![CDATA[zend framework 2]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12250</guid> <description><![CDATA[In today's tutorial come and learn the new HTML5-specific form elements available in Zend Framework 2. You'll learn how they work, how to use them, what they look like.]]></description> <content:encoded><![CDATA[<h2>Introduction</h2><p>In this tutorial, I&#8217;ll be taking you through a few of the new HTML5-specific form elements available in the new Zend Framework 2. We&#8217;ll see: how they work, how to use them, so you can also see what they&#8217;re like.</p><p>This will be coupled with a good set of screenshots &#8211; so you know what they look like. By the end of this tutorial, you should be well on your way to being able to have fully HTML5 interfaces in your applications.</p><p>If you&#8217;re not familiar with forms in Zend Framework 2 yet, <a
href="http://zf2.readthedocs.org/en/latest/modules/zend.form.intro.html">check out the online documentation first</a>. Alternatively, read the introductory series here on Malt Blue:</p><ul><li><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection">Dependency Injection</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart">Zend Framework 2 Modules</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction">Event Manager</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager">Service Manager</a></li></ul><h2>Difficulty</h2><p>Beginner</p><h2>Time Required</h2><p>20 Minutes</p><h2>Please Note:</h2><p>The language set on the iPhone in the screenshots in this tutorial is German. This shouldn&#8217;t cause any real issues. But, here is a translation of the words that you are not likely to know if you&#8217;re not familiar with German:</p><ul><li><strong>zurück</strong> &#8211; back</li><li><strong>weiter</strong> &#8211; forward</li><li><strong>fertig</strong> &#8211; finish/done</li><li><strong>löschen</strong> &#8211; clear/delete/empty</li></ul><h2>Why HTML5 elements?</h2><p>As the online world becomes more mobile-centric, we need to be both aware of what this means and how we as developers, specializing in the Zend Framework, can implement them in the applications we&#8217;re building.</p><p>Here are a few facts from the recent <a
href="http://static.zend.com/topics/Zend-Developer-Pulse-report-Q2-2013-0523-EN.pdf">Zend Developer Pulse Report</a>:</p><ul><li>[IDC predicts](http://www.computerworld.com/s/<br
/> article/9219932/Most<em>will</em>access<em>Internet</em>via<em>mobile</em>devices<em>by</em>2015<em>IDC</em>says) that by 2015, more people will access the Internet through a smartphone than a desktop</li><li><a
href="http://www.vertic.com/blog/year_of_the_enterprise_tablet_infographic/">By 2015</a>, mobile app development projects will outnumber native PC projects <strong>by a ratio of 4-1</strong></li><li>A full <strong>91% of application developers</strong> plan to deliver content and services to a mobile audience</li><li><a
href="http://www.idc.com/research/Predictions13/downloadable/238044.pdf">According to IDC:</a> &#8220;<em>Sales of smart mobile devices – smartphones and tablets – will grow by 20%, generate 20% of all IT sales and drive 57% of all IT market growth.</em>&#8221;</li></ul><p>These are impressive numbers and clearly show 2 things:</p><ul><li>Where the market is going</li><li>Why mobile development is a good place to focus your development efforts</li></ul><p>So today, let&#8217;s dip our toes in the HTML5 &amp; Mobile development waters and get just a taste of what is available to us.</p><p><strong>iPhone Warning</strong>: If you&#8217;re a Windows Phone or Blackberry supporter you may be a little disappointed by what you&#8217;re about to see. The screenshots in today&#8217;s post primarily focus around iPhone 5. However, I will be including some screenshots from Android, using the HTC One shortly.</p><h2>The HTML5 Form Elements?</h2><p>If you&#8217;re familiar with <a
href="http://www.w3.org/html/wg/drafts/html/master/">the HTML5 specification</a>, you&#8217;ll know that there are a number of new elements. In the space that this tutorial has available however, I&#8217;ll only be focusing on just a few, specifically input.</p><p>These are:</p><ul><li><strong>Telephone (tel)</strong> &#8211;  control for entering a telephone number; line-breaks are automatically removed from the input value, but no other syntax is enforced. You can use attributes such as pattern and maxlength to restrict values entered in the control.</li><li><strong>Email</strong> &#8211; A field for editing an e-mail address.</li><li><strong>Url</strong> &#8211; A field for editing a <acronym
title="Uniform Resource Locator">URL</acronym>. The user may enter a blank or invalid address. Line-breaks are automatically removed from the input value. You can use attributes such as pattern and maxlength to restrict values entered in the control.</li><li><strong>DateTime (date, datetime, datetime-local)</strong> &#8211; A control for entering a date and time (hour, minute, second, and fraction of a second) based on UTC time zone.</li></ul><p>For further information about each of these fields, and the rest of the specification, <a
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input?redirectlocale=en-US&amp;redirectslug=HTML%2FElement%2FInput">check out the documentation over at MDN (Mozilla Developer Network)</a>.</p><h2>Implementing Them</h2><p>Implementing them is really trivial, no more difficult than implementing any of the other fields that you&#8217;ve been implementing up until now. The way that I&#8217;ve approached it is through form code, with a minimalist configuration.</p><p>A lot of these examples you&#8217;ll see are very similar. That&#8217;s OK, as there&#8217;s generally not a lot that you have to do which is different.</p><h2>Email</h2><p><a
href="http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction/attachment/email-field" rel="attachment wp-att-12256"><img
src="http://www.maltblue.com/wp-content/uploads/2013/05/email-field.png" alt="Zend Frameowrk 2 Email Field" width="308" height="546" class="aligncenter size-full wp-image-12256" /></a></p><p>What about email? Whether that&#8217;s a <em>registration</em>, <em>forgot password</em> or <em>user management form</em>, it&#8217;s arguably one of the most important fields in a form.</p><p>As you can see, in the image above, when the user clicks in an email field, the keyboard is changed to only provide characters that match the email specification. The email field will validate that value entered in the field represents a valid email address.</p><h3>View Script</h3><p>As with the telephone example above, I&#8217;ve rendered the email element in the view script using the viewscript form helpers (<em>formLabel</em> and <em>formEmail</em>).</p><pre>
&lt;div class="control-group"&gt;
    &lt;?php
    $active = $form-&gt;get('eventCategoryActive');
    echo $this-&gt;formLabel($active);
    ?&gt;
    &lt;div class="controls"&gt;
        &lt;?php
        echo $this-&gt;formEmail($active);
        echo $this-&gt;formElementErrors($active);
        ?&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre><h3>Form Code</h3><p>Now for the code. As with the telephone element, I&#8217;m adding the email element to the form by specifying the type as &#8216;<strong>Zend\Form\Element\Email</strong>&#8216;. I&#8217;ve then specified the name and label values.</p><pre>
$this-&gt;add(array(
    'type' =&gt; 'Zend\Form\Element\Email',
    'name' =&gt; 'userWebsite',
    'options' =&gt; array(
        'label' =&gt; 'Website',
    )
));
</pre><p>This configuration allows for one email address. If you want to allow for multiple email addresses, then add specify multiple to true in the options array, as follows:</p><pre>
$this-&gt;add(array(
    'type' =&gt; 'Zend\Form\Element\Email',
    'name' =&gt; 'userWebsite',
    'options' =&gt; array(
        'label' =&gt; 'Website',
        'multiple' =&gt; true
    )
));
</pre><h2>Url</h2><p><a
href="http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction/attachment/url-field" rel="attachment wp-att-12259"><img
src="http://www.maltblue.com/wp-content/uploads/2013/05/url-field.png" alt="Zend Frameowrk 2 Url Field" width="308" height="546" class="aligncenter size-full wp-image-12259" /></a></p><p>Arguably, after emails (or maybe before), come URLs. Whether it&#8217;s a <em>web address</em>, <em>ftp address</em> or similar, they&#8217;re one of the most commonly used aspects on the web.</p><p>In the screenshot above, you see how the keyboard on the iPhone 5 has changed so that only allowed characters are available, with an extra <strong>.com</strong> button to help along. This element transparently adds the <strong>Zend\Validator\Uri</strong> validator, which ensures that the value entered is a value <acronym
title="Uniform Resource Identifier">URI</acronym>.</p><h3>View Script</h3><p>Here, I&#8217;ve rendered the url field using the formUrl ViewScript helper, as in previous examples.</p><pre>
&lt;div class="control-group"&gt;
    &lt;?php
    $active = $form-&gt;get('eventCategoryActive');
    echo $this-&gt;formLabel($active);
    ?&gt;
    &lt;div class="controls"&gt;
        &lt;?php
        echo $this-&gt;formUrl($active);
        echo $this-&gt;formElementErrors($active);
        ?&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre><h3>Form Code</h3><p>As with the previous examples, I&#8217;m adding the <acronym
title="Uniform Resource Locator">URL</acronym> element to the form by specifying the type as &#8216;<strong>Zend\Form\Element\Url</strong>&#8216;. I&#8217;ve then specified the name and label values.</p><pre>
$this-&gt;add(array(
    'type' =&gt; 'Zend\Form\Element\Url',
    'name' =&gt; 'userWebsite',
    'options' =&gt; array(
        'label' =&gt; 'Website',
    )
));
</pre><h2>DateTime</h2><p><a
href="http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction/attachment/datetime-field" rel="attachment wp-att-12253"><img
src="http://www.maltblue.com/wp-content/uploads/2013/05/datetime-field.png" alt="Zend Frameowrk 2 Date Field" width="308" height="546" class="aligncenter size-full wp-image-12253" /></a></p><p>One last example. This one is one that I feel is really important and consequently very helpful for users &#8211; the Date &amp; Time field.</p><p>How often do we, as developers &amp; designers, have to put in extra work or jump through hoops to ensure that the user enters the correct information when supplying dates and times? Arguably, too often is a pretty close answer. Right?</p><p>Well the HTML5 DateTime element goes a long way to cutting this effort down (at least on a Smart Phone). In the screenshot above, you can see that when the user&#8217;s given focus to the DateTime field, the keyboard has changed to only allow them to enter a valid date, using the ultra-efficient date input keyboard available under iOS.</p><p>Now, all we need to do is to convert one value sent from the form, into an applicable format required to be stored in our datasource (whether <em>MySQL</em>, <em>PostgreSQL</em>, <em>MongoDB</em> or whatever). When the user is finished, the field appears as a select box showing the specified date.</p><h3>View Script</h3><p>As with the previous examples, I&#8217;ve used the form ViewScript helpers to render the element. Nothing new here.</p><pre>
&lt;div class="control-group"&gt;
    &lt;?php
    $active = $form-&gt;get('eventCategoryActive');
    echo $this-&gt;formLabel($active);
    ?&gt;
    &lt;div class="controls"&gt;
        &lt;?php
        echo $this-&gt;formSelect($active);
        echo $this-&gt;formElementErrors($active);
        ?&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre><h3>Form Code</h3><p>Similarly, with the other elements, I&#8217;ve called the add method, passing in an array, specifying the type (&#8216;<strong>Zend\Form\Element\Date</strong>&#8216;), name and label values for the element, which has done the majority of the heavy lifting for us.</p><pre>
$this-&gt;add(array(
    'type' =&gt; 'Zend\Form\Element\Date',
    'name' =&gt; 'userWebsite',
    'options' =&gt; array(
        'label' =&gt; 'Website',
    )
));
</pre><p>If we wanted to provide even more guidance to the user, we could have specified a minimum and maximum date range in the additional attributes array (as below). Some examples of where this can be useful are:</p><ul><li>Users being over or under a certain age</li><li>Users being within a certain age range</li><li>Defaulting to a short, meaningful range so the user doesn&#8217;t need to search too much</li></ul><h3>Specifying the Minimum and Maximum Date Range</h3><pre>
'attributes' =&gt; array(
         'min' =&gt; '2012-01-01',
         'max' =&gt; '2020-01-01',
 )
</pre><h2>Telephone</h2><p><a
href="http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction/attachment/tel-field" rel="attachment wp-att-12258"><img
src="http://www.maltblue.com/wp-content/uploads/2013/05/tel-field.png" alt="Zend Framework 2 HTML5 Telephone Field " width="308" height="546" class="aligncenter size-full wp-image-12258" /></a></p><p>At this point, given the wide differences in international phone number formats, no validation is performed by the browser. However, what we do get is, on mobile devices, a keyboard that is customized to entering the correct type of information.</p><p>You can see in the screenshot above that when you set focus in the field, that the keyboard changes to one that only provides options for entering phone number information (including the international dialing prefixes; i.e., <em>+61, +49 etc</em>).</p><h3>View Script</h3><p>In the view script output below, you&#8217;ll see that I&#8217;m using the <strong>formTel</strong> and <strong>formLabel</strong> view helpers. This will, assuming that the element is a telephone field, print out a <a
href="http://www.w3.org/TR/html-markup/input.tel.html">telephone type field</a>.</p><pre>
&lt;div class="control-group"&gt;
    &lt;?php
        $active = $form-&gt;get('eventCategoryActive');
        echo $this-&gt;formLabel($active);
    ?&gt;
    &lt;div class="controls"&gt;
        &lt;?php
            echo $this-&gt;formTel($active);
            echo $this-&gt;formElementErrors($active);
        ?&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre><h3>Form Code</h3><p>Now that we have the view script in place, let&#8217;s have a look at the code for creating a phone number field. Firstly, I&#8217;ve created <a
href="http://zf2.readthedocs.org/en/latest/modules/zend.form.intro.html">a new Zend Form object</a>, called <strong>$form</strong>.</p><p>I&#8217;ve then called <strong>add</strong> on this, which adds a new Form Element, specifying the type, name and options. You can see that it&#8217;s of type <strong>Telephone</strong>, the name is <strong>userPhone</strong> and I&#8217;ve set the label value to <strong>Phone Number</strong>.</p><pre>
$form = new \Zend\Form;
$form-&gt;add(array(
    'type' =&gt; 'Zend\Form\Element\Number',
    'name' =&gt; 'userPhone',
    'options' =&gt; array(
        'label' =&gt; 'Phone Number',
    )
));
</pre><p>Nothing hard about this one. Now your user has less work to do to enter phone and fax numbers on your forms.</p><h2>Conclusion</h2><p>So there we have it. We&#8217;ve gone through four of the new HTML5 elements available in Zend Framework 2 (Telephone, Email, <acronym
title="Uniform Resource Locator">URL</acronym> and DateTime). As we&#8217;ve touched on, there are a number of other new elements, including <em>Month</em>, <em>Color</em>, <em>Time</em>, <em>Week</em> and <em>Range</em>.</p><p>We&#8217;ve seen what they look like in the most popular mobile browser, Safari on iOS, and how they make the job of user input simpler, quicker and easier to complete. You&#8217;re now in a position to use the remainder of the new HTML5 elements, as needed, in your applications.</p><p>Given the continued growth of smart phones and mobile internet access and the expected usage numbers over the next 5 years, these fields will help ensure that they&#8217;re the ones that continue to prosper and are thoroughly enjoyed by users.</p><p>For more information about the elements that I&#8217;ve used on today&#8217;s tutorial, or any of the other elements available in Zend Framework 2, be sure to <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.form.elements.html">check out the excellent online documentation</a>.</p><p>Till then, share your thoughts, in the comments, about how you&#8217;re using the new HTML5 elements in your applications. How are they enhancing your applications? Have your users been giving you positive feedback?</p><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-2561" ><a
href="http://www.maltblue.com/php/zend-form-multiple-submit-buttons" class="wp_rp_thumbnail"><img
width="84" height="150" src="http://www.maltblue.com/wp-content/uploads/2011/09/simple-decision-tree.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form &#8211; Multiple Submit Buttons" title="" /></a><a
href="http://www.maltblue.com/php/zend-form-multiple-submit-buttons" class="wp_rp_title">Zend Form &#8211; Multiple Submit Buttons</a></li><li
data-position="1" data-poid="in-12061" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/Post-Image-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Modules &#8211; The Application&#8217;s Heart" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_title">Zend Framework 2 Modules &#8211; The Application&#8217;s Heart</a></li><li
data-position="2" data-poid="in-12103" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Event Manager &#8211; A Gentle Introduction" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" class="wp_rp_title">Zend Framework 2 Event Manager &#8211; A Gentle Introduction</a></li><li
data-position="3" data-poid="in-12234" ><a
href="http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 &#8211; Hydrators, Models and the TableGateway Pattern" title="" /></a><a
href="http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern" class="wp_rp_title">Zend Framework 2 &#8211; Hydrators, Models and the TableGateway Pattern</a></li><li
data-position="4" data-poid="in-9461" ><a
href="http://www.maltblue.com/php/zend-form-mastery-with-zend-config-part-2-core-form-configuration" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form Mastery with Zend Config &#8211; Part 2 Core Form Configuration" title="" /></a><a
href="http://www.maltblue.com/php/zend-form-mastery-with-zend-config-part-2-core-form-configuration" class="wp_rp_title">Zend Form Mastery with Zend Config &#8211; Part 2 Core Form Configuration</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=_R_7MARwmhU:id3DarUVKAQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=_R_7MARwmhU:id3DarUVKAQ:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=_R_7MARwmhU:id3DarUVKAQ:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=_R_7MARwmhU:id3DarUVKAQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=_R_7MARwmhU:id3DarUVKAQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=_R_7MARwmhU:id3DarUVKAQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=_R_7MARwmhU:id3DarUVKAQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=_R_7MARwmhU:id3DarUVKAQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=_R_7MARwmhU:id3DarUVKAQ:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=_R_7MARwmhU:id3DarUVKAQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=_R_7MARwmhU:id3DarUVKAQ:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/_R_7MARwmhU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction/feed</wfw:commentRss> <slash:comments>0</slash:comments> <media:content url="http://feedproxy.google.com/~r/MaltBlue/~5/pvqiVFI6I4k/Zend-Developer-Pulse-report-Q2-2013-0523-EN.pdf" fileSize="1168550" type="application/pdf" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>In today's tutorial come and learn the new HTML5-specific form elements available in Zend Framework 2. You'll learn how they work, how to use them, what they look like.</itunes:subtitle><itunes:summary>In today's tutorial come and learn the new HTML5-specific form elements available in Zend Framework 2. You'll learn how they work, how to use them, what they look like.</itunes:summary><itunes:keywords>Beginner, Tutorial, html5, Zend Form, zend framework 2</itunes:keywords><feedburner:origLink>http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/MaltBlue/~5/pvqiVFI6I4k/Zend-Developer-Pulse-report-Q2-2013-0523-EN.pdf" length="1168550" type="application/pdf" /><feedburner:origEnclosureLink>http://static.zend.com/topics/Zend-Developer-Pulse-report-Q2-2013-0523-EN.pdf</feedburner:origEnclosureLink></item> <item><title>Zend Framework 2 – Hydrators, Models and the TableGateway Pattern</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/f2pNUo7oATI/zendframework2-hydrators-models-tablegateway-pattern</link> <comments>http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern#comments</comments> <pubDate>Wed, 15 May 2013 16:00:17 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[Hydrators]]></category> <category><![CDATA[Models]]></category> <category><![CDATA[TableGateway Pattern]]></category> <category><![CDATA[zend framework 2]]></category> <category><![CDATA[ZF2]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12234</guid> <description><![CDATA[Today's tutorial walks through using the TableGateway and Hydrator objects along with the Zend Framework 2 ServiceLocator to create models, which not coupled to a specific data source. Come find out how simple it is. ]]></description> <content:encoded><![CDATA[<p><a
href="http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern/attachment/hydrator-tablegateway-model-post-image" rel="attachment wp-att-12241"><img
src="http://www.maltblue.com/wp-content/uploads/2013/05/hydrator-tablegateway-model-post-image.jpg" alt="hydrator-tablegateway-model-post-image" width="600" height="180" class="alignleft size-full wp-image-12241" /></a></p><h2>Synopsis</h2><p>Zend Framework 2 comes packed with an assortment of new features and functionality and greatly streamlines how common scenarios, such as interacting with datasources and application configuration and caching are implemented.</p><p>Whether it&#8217;s the new <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.form.elements.html#html5-elements">HTML5 form elements</a> and view helpers, the new implementation of <a
href="http://framework.zend.com/manual/2.1/en/modules/zend.http.html">Zend\Http</a>, the Service Manager, the Event Manager or that <a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart">Modules are now first-class citizens</a> &#8211; you can&#8217;t help but see that it&#8217;s bursting at the seams.</p><p>But one set of features has really been helping me of late ones that really have me smiling; these are: <strong>Hydrators</strong>, <strong>Models</strong> and <strong>Table Gateways</strong>. If you&#8217;re new to ZF2 or database interaction with frameworks, then you&#8217;re in a perfect position as today&#8217;s post will be giving you a good introduction to the basics of using both together.</p><p>We&#8217;ll be working through sample code which will show you how to create models, which are decoupled from data source logic, yet via a simple ServiceManager configuration and a not too complex hydrator, will be able to extract information from a database query and auto-fill the model with it &#8211; ready to be used.</p><h2>Why This Approach?</h2><p>In the past, in Zend Framework 1, when you wanted to have a datasource agnostic model, it wasn&#8217;t always so simple to implement. Though there is still a lot of talk of <acronym
title="Pre-Hypertext Processing">PHP</acronym> &amp; MySQL; we all know that there is a veritable cornucopia of choice, including <em>MongoDB</em>, <em>CouchDB</em>, <em>PostgreSQL</em>, <em>Cassandra</em>, <em>Redis</em> and much, much, more.</p><p>Applications we write can start out with simple, modest needs. At first, maybe a basic RDBMS will suffice. But, as your needs change and grow, it&#8217;s nice to know that, without too much code refactoring, you can change around to match.</p><p>Today&#8217;s approach does this &#8211; allowing for a nearly transparent data source, which the model class knows nothing about. It ensures that irrespective of where the information comes from, it will be transformed so that the model class will be able to use it.</p><h2>How Does It Work?</h2><p><a
href="http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern/attachment/database-to-model-flow-diagram" rel="attachment wp-att-12237"><img
src="http://www.maltblue.com/wp-content/uploads/2013/05/database-to-model-flow-diagram.png" alt="TableGateway to Database Model mapping" width="546" height="110" class="alignleft size-full wp-image-12237" /></a></p><p>In a nutshell here&#8217;s how it works. Firstly <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.db.table-gateway.html">a TableGateway class</a> performs the specific interaction with the datasource, such as <em>fetching all records</em>, <em>deleting</em>, <em>adding</em> and <em>updating</em> records. In this case it is a MySQL 5 database. The, the hydrator class maps (and transforms where applicable) the information retrieved from the TableGateway to the Model class.</p><p>In the <strong>getServiceConfig</strong> method in our Module class, the two are bound together and the Hydrator is configured. Finally, in a controller action, we can then access the datasource, querying records, auto-populating our Model and then iterate over the records. Sound good? Great!</p><p><strong>Let&#8217;s get going!</strong></p><h2>The Table Gateway Class</h2><p>Here we have the TableGateway class. I&#8217;ve called it UserTable as it is responsible for managing information in a user table. I&#8217;ve kept it simple and just focused on the retrieving of records skipping over the remainder of the CRUD operations.</p><p>In the constructor, we passing in a TableGateway object, which will be made available <a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager">in the ServiceManager configuration</a>. This provides us with simple access to the database. In the <strong>fetchAll</strong> function, we retrieve a result set by calling the <strong>select</strong> method on the TableGateway object.</p><p>The calls to <strong>buffer</strong> and <strong>next</strong> aren&#8217;t strictly necessary &#8211; but have been included as, in the list action, a Paginator object is returned. Errors will be thrown if these two methods aren&#8217;t called. Not much to it &#8211; <strong>right?</strong></p><pre>
namespace MaltBlueCore\Model;
use Zend\Db\TableGateway\TableGateway;
class UserTable
{
    protected $tableGateway;
    public function __construct(TableGateway $tableGateway)
    {
        $this-&gt;tableGateway = $tableGateway;
    }
    public function fetchAll()
    {
        $resultSet = $this-&gt;tableGateway-&gt;select();
        $resultSet-&gt;buffer();
        $resultSet-&gt;next();
        return $resultSet;
    }
}
</pre><h2>The Model Class</h2><p>Now we have the User class. As you can see, this class has no code that relates to any kind of datasource or database. Here, we&#8217;re only concerned about the data that we want to work with &#8211; in this case a:</p><ul><li>user id</li><li>name</li><li>active flag</li><li>record creation date</li></ul><p>The <strong>exchangeArray</strong> method is a common mention in ZF2 for passing in a dataset, such as an array in this case and auto-populating the object. You can see that I&#8217;ve set all the properties from the respective array key. Nice clean and simple.</p><pre>
namespace MaltBlueCore\Model;
class User
{
    public $userId;
    public $userName;
    public $userActive;
    public $createdDate;
    public function exchangeArray($data)
    {
        if (isset($data['userName'])) {
            $this-&gt;userName = $data['userName'];
        } else {
            $this-&gt;userName = null;
        }
        if (isset($data['userActive'])) {
            $this-&gt;userActive = $data['userActive'];
        } else {
            $this-&gt;userActive = null;
        }
        if (isset($data['userId'])) {
            $this-&gt;userId = $data['userId'];
        } else {
            $this-&gt;userId = null;
        }
        if (isset($data['createdDate'])) {
            $this-&gt;createdDate = $data['createdDate'];
        } else {
            $this-&gt;createdDate = null;
        }
    }
    public function getArrayCopy()
    {
        return get_object_vars($this);
    }
}
</pre><h2>The Hydrator</h2><p>The Hydrator is the key aspect of the setup. It&#8217;s what maps the database field names on one side, to the entity properties on the other. However, it doesn&#8217;t store this information internally &#8211; <em>as you&#8217;ll see</em>. I went for a more generic approach, one class which could be applied to any table.</p><p>What this does is allow for an array of <strong>Column Names -> Entity Properties</strong> to be passed in as an array and, when its hydrate method is called, will transfer the respective information from the datasource to the model object.</p><pre>
namespace MaltBlueCore\Hydrator;
use ReflectionMethod;
use Traversable;
use Zend\Stdlib\Exception;
use Zend\Stdlib\Hydrator\AbstractHydrator;
use Zend\Stdlib\Hydrator\HydratorOptionsInterface;
class TableEntityMapper
    extends AbstractHydrator
    implements HydratorOptionsInterface
{
    protected $_dataMap = true;
    public function __construct($map)
    {
        parent::__construct();
        $this-&gt;_dataMap = $map;
    }
    public function extract($object) {}
</pre><p>In the hydrate method, we pass in the datasource and the model. If the model is not an object, we throw a <strong>BadMethodCallException</strong>. If it is, we proceed and iterate over the data available.</p><p>If there is a mapping available, we use that to determine which field in the model matches with which field in the datasource. If it doesn&#8217;t (if no mapping is required), we set the property directly. Any unknown or missing properties are silently skipped over.</p><pre>
    public function hydrate(array $data, $object)
    {
        if (!is_object($object)) {
            throw new Exception\BadMethodCallException(sprintf(
                '%s expects the provided $object to be a <acronym title="Pre-Hypertext Processing">PHP</acronym> object)',
                __METHOD__
            ));
        }
        foreach ($data as $property =&gt; $value) {
            if (!property_exists($this, $property)) {
                if (in_array($property, array_keys($this-&gt;_dataMap))) {
                    $_prop = $this-&gt;_dataMap[$property];
                    $object-&gt;$_prop = $value;
                } else {
                    // unknown properties are skipped
                }
            } else {
                $object-&gt;$property = $value;
            }
        }
        return $object;
    }
}
</pre><h2>The Module Service Configuration</h2><p>In the Module configuration, is where we tie everything together. I&#8217;ve been <a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager">writing about the ServiceManager</a> previously and I&#8217;ve listed some excellent links in the further reading section, which I encourage you to check out. Without this component, the rest really would not be possible.</p><p>Firstly we register an object in the factories list, which initialises the UserTable model we covered earlier, passing it the TableGateway object. Following that, we have the configuration for the TableGateway object. I have much <a
href="http://blog.evan.pro/zf2-tablegateway-hydration">to thank Evan Coury for</a> in the approach that I&#8217;ve taken here.</p><p>What this does is to retrieve the application database adapter and initialise an instance of the hydrator that we previously covered, where we provide it with the mapping array; the table column names on the left and the model properties on the right.</p><p>We then provide the User model as the prototype to use with the <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.db.result-set.html#zend-db-resultset-hydratingresultset">HydratingResultSet object</a>. If you&#8217;re not familiar with it, the HydratingResultSet is a truly amazing part of Zend Framework 2.</p><p>I&#8217;ll not try an invent the wheel and quote directly from the manual:</p><blockquote><p>Zend\Db\ResultSet\HydratingResultSet is a more flexible ResultSet object that allows the developer to choose an appropriate “hydration strategy” for getting row data into a target object.</p><p>While iterating over results, HydratingResultSet will take a prototype of a target object and clone it once for each row. The HydratingResultSet will then hydrate that clone with the row data.</p></blockquote><p>In essence, we provide the model, data and hydrator and it takes care of the rest. Following that, we return a new TableGateway object, specifying the underlying table, <strong>tbluser</strong>, that will be the source of the data, the database adapter and the resultset object we&#8217;ve just initialised.</p><p>Now, we have the two sides of the equation beautifully joined. Should the datasource change, the table name, the properties or column names, we only need make a slight adjustment here. No other classes or code need be touched.</p><pre>
public function getServiceConfig()
{
    return array(
        'factories' =&gt; array(
            'MaltBlueAdmin\Model\UserTable' =&gt;  function($sm) {
                $tableGateway = $sm-&gt;get('UserTableGateway');
                $table = new UserTable($tableGateway);
                return $table;
            },
            'UserTableGateway' =&gt; function ($sm) {
                $dbAdapter = $sm-&gt;get('Zend\Db\Adapter\Adapter');
                $hydrator = new \MaltBlueCore\Hydrator\TableEntityMapper(
                    array(
                        'UserID' =&gt; 'userId',
                        'UserName' =&gt; 'userName',
                        'StatusID' =&gt; 'userActive',
                        'CreatedOn' =&gt; 'createdDate'
                    ));
                $rowObjectPrototype = new \MaltBlueCore\Model\User;
                $resultSet = new \Zend\Db\ResultSet\HydratingResultSet(
                    $hydrator, $rowObjectPrototype
                );
                return new TableGateway(
                    'tbluser', $dbAdapter, null, $resultSet
                );
            }
        )
    );
}
</pre><h2>The Controller</h2><p>Ok, now we show how to use it. In our controller, we have a list action, which, as the name implies, will retrieve a list of records, which we will iterate over.</p><pre>
namespace MaltBlueManagementAdmin\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use MaltBlueCore\Model\User;
use MaltBlueCore\Form\AddUserForm;
use MaltBlueCore\Form\EditUserForm;
class userController extends AbstractActionController
{
    protected $userTable;
    protected $_createUserForm;
    public function listAction()
    {
</pre><p>Firstly, we retrieve a copy of the userTable object through the Service Locator. We then call the fetchAll method, retrieving all rows from the table. I&#8217;ve used a filter iterator and a paginator to make for a more juicy example.</p><p>The filter iterator will only return records where the userActive field is set to &#8220;active&#8221;. All others will be skipped. This iterator is then passed to the Zend\Paginator object, a few properties are set on it and is returned in the ViewModel, ready to be iterated over in the view script.</p><pre>
        $sm = $this-&gt;getServiceLocator();
        $userTable = new \MaltBlueCore\Model\UserTable(
            $sm-&gt;get('userTableGateway')
        );
        $filterIterator = new StatusFilterIterator(
            $userTable-&gt;fetchAll(), "active"
        );
        $paginator = new Paginator(new Iterator($filterIterator));
        $paginator-&gt;setCurrentPageNumber(
            $this-&gt;params()-&gt;fromRoute('page')
        );
        $paginator-&gt;setItemCountPerPage(
            $this-&gt;params()-&gt;fromRoute('perPage', 10)
        );
        return new ViewModel(array(
            'paginator' =&gt; $paginator,
            'status' =&gt; $this-&gt;params()-&gt;fromRoute('status')
        ));
    }
}
</pre><h2>Conclusion</h2><p>So, there we have it. With, only a little bit of code, we&#8217;ve created a model that is able to interact with a variety of data sources, yet avoid coupling to tightly at the same time. If we move from MySQL to PostgreSQL or Redis, then the requisite parts can be changed to suit.</p><p>Now, I&#8217;m not as experienced with hydrators, data mappers and the table gateway pattern as others. So I&#8217;d love to get your feedback. Tell me where this approach can be improved. Are there other aspects of ZF2 that can take it further &#8211; such as <a
href="http://juriansluiman.nl/en/article/125/strategies-for-hydrators-a-practical-use-case">Strategies by Jurian Sluiman</a>.</p><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-12103" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Event Manager &#8211; A Gentle Introduction" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" class="wp_rp_title">Zend Framework 2 Event Manager &#8211; A Gentle Introduction</a></li><li
data-position="1" data-poid="in-12061" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/Post-Image-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Modules &#8211; The Application&#8217;s Heart" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_title">Zend Framework 2 Modules &#8211; The Application&#8217;s Heart</a></li><li
data-position="2" data-poid="in-11989" ><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Core Concepts &#8211; Dependency Injection" title="" /></a><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection" class="wp_rp_title">Zend Framework 2 Core Concepts &#8211; Dependency Injection</a></li><li
data-position="3" data-poid="in-12250" ><a
href="http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 &#8211; The New HTML5 Form Fields" title="" /></a><a
href="http://www.maltblue.com/tutorial/zf2-html5-form-field-introduction" class="wp_rp_title">Zend Framework 2 &#8211; The New HTML5 Form Fields</a></li><li
data-position="4" data-poid="in-12119" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/zf2-eventmanager-feature-image-resized-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 ServiceManager &#8211; Web Application Development Simplified" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" class="wp_rp_title">Zend Framework 2 ServiceManager &#8211; Web Application Development Simplified</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=f2pNUo7oATI:L6qMldOVfCM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=f2pNUo7oATI:L6qMldOVfCM:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=f2pNUo7oATI:L6qMldOVfCM:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=f2pNUo7oATI:L6qMldOVfCM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=f2pNUo7oATI:L6qMldOVfCM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=f2pNUo7oATI:L6qMldOVfCM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=f2pNUo7oATI:L6qMldOVfCM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=f2pNUo7oATI:L6qMldOVfCM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=f2pNUo7oATI:L6qMldOVfCM:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=f2pNUo7oATI:L6qMldOVfCM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=f2pNUo7oATI:L6qMldOVfCM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/f2pNUo7oATI" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern/feed</wfw:commentRss> <slash:comments>15</slash:comments> <feedburner:origLink>http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern</feedburner:origLink></item> <item><title>Use RouteMatch in Zend Framework 2 For Easy Routing</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/OakT3uvDEqA/use-zend-framework-2-routematch-for-dynamic-routing</link> <comments>http://www.maltblue.com/tutorial/use-zend-framework-2-routematch-for-dynamic-routing#comments</comments> <pubDate>Wed, 01 May 2013 14:12:51 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[Request]]></category> <category><![CDATA[RouteMatch]]></category> <category><![CDATA[Router]]></category> <category><![CDATA[Zend Framework]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12214</guid> <description><![CDATA[Today using Zend Framework 2 RouteMatch, Router and Request objects, I show you an easy way to dynamically update the current route. It's almost painlessly simple.]]></description> <content:encoded><![CDATA[<h2>Synopsis</h2><p>Today using Zend Framework 2 RouteMatch, Router and Request objects, I show you an easy way to dynamically update the current route. It&#8217;s almost painlessly simple.</p><h2>Working with Routes</h2><p>In a Zend Framework 2 application that I&#8217;ve been building lately, I came across an unexpected routing situation; one that I&#8217;d not previously encountered. It started off pretty simply, with a small, segment, route that allowed me to render a page with two parameters: <strong>record status</strong> and <strong>page number</strong>.</p><p>It was for a fairly typical page that uses the <strong>Zend Paginator</strong> to paginate a large record set object and a <em>status</em> parameter to filter down the records displayed.</p><p>Well, like most things in web application development, what starts out simply in the beginner often grows more complex over time. So too is my once simple route. From humble origins, it&#8217;s evolved to have the following parameters:</p><table
style="width:100%;"><thead><tr><th
align="left"><strong>Parameter Name</strong></th><th
align="left"><strong>Description</strong></th></tr></thead><tbody><tr><td
align="left">status</td><td
style="text-align: left;" align="center">The record status</td></tr><tr><td
align="left">page</td><td
style="text-align: left;" align="center">The current page number</td></tr><tr><td
align="left">perPage</td><td
style="text-align: left;" align="center">The amount of results per page</td></tr><tr><td
align="left">sortBy</td><td
style="text-align: left;" align="center">The column to sort records by</td></tr><tr><td
align="left">sortDir</td><td
style="text-align: left;" align="center">The sort direction (asc/desc)</td></tr><tr><td
align="left">filterLetter</td><td
align="left">The letter to filter the records by (a &#8211; z)</td></tr></tbody></table><p>Here&#8217;s a route in questions, so you can see how it&#8217;s configured:</p><pre>'category-list' =&gt; array(
    'type'    =&gt; 'segment',
    'options' =&gt; array(
        'route'    =&gt; '/admin/category/list[/status/:status]
                          [/page/:page][/perPage/:perPage][/sortBy/:sortBy]
                          [/sortDir/:sortDir][/filterLetter/:filterLetter]',
        'defaults' =&gt; array(
            '__NAMESPACE__' =&gt; 'MaltBlueAdmin\Controller',
            'controller'    =&gt; 'Category',
            'action'        =&gt; 'list',
            'status' =&gt; 'all',
            'page' =&gt; 1,
            'perPage' =&gt; 10
            'sortBy' =&gt; "category-name"
            'sortDir' =&gt; "asc"
            'filterLetter' =&gt; ""
        ),
    ),
),
</pre><p>You can see that, as mentioned, I&#8217;m using the <a
href="http://zf2.readthedocs.org/en/latest/modules/zend.mvc.routing.html#zend-mvc-router-http-segment">segment route type</a> and all of the parameters are optional and have meaningful defaults. &#8220;What&#8217;s the big problem&#8221;, you ask. It&#8217;s an easy route to construct, has meaningful defaults. Add it to your module&#8217;s <strong>module.config.php</strong> and get going.</p><p>Well, I found it not so easy. You see, the route forms the foundation of a toolbar I&#8217;ve been creating in a custom view helper. It aims to give the user a large amount of power to filter the records available, so they can get to them quickly &#8211; but without overwhelming them with choice.</p><p>The toolbar works as follows: it sits atop the list of paginated records, followed by the list of records, then finally the pagination control. By default, no filter options are set. As desired, the user can then add different filters, of the types above. Have a look in the screenshots below and you&#8217;ll see a bit of what it looks like.</p><p><a
href="http://www.maltblue.com/tutorial/use-zend-framework-2-routematch-for-dynamic-routing/attachment/sample-list-display-2" rel="attachment wp-att-12221"><img
src="http://www.maltblue.com/wp-content/uploads/2013/05/sample-list-display1.png" alt="sample-list-display" width="600" height="432" class="alignleft size-full wp-image-12221" /></a></p><p>In a nutshell, here is the problem. We&#8217;ve set the route parameters and rendered the page. <em>How can we change, add or remove a parameter and re-render the current page, simply and easily</em>? Said differently, when the user clicks a filter, how can I redirect to the same page, enable that filter and re-render paginated results?</p><p><a
href="http://www.maltblue.com/tutorial/use-zend-framework-2-routematch-for-dynamic-routing/attachment/filter-by-starting-letter" rel="attachment wp-att-12215"><img
class="size-medium wp-image-12215 alignnone" alt="Custom Zend Framework 2 ViewHelper with Paginated List - Filter by starting letter" src="http://www.maltblue.com/wp-content/uploads/2013/05/filter-by-starting-letter-300x188.png" width="300" height="188" /></a></p><p><a
href="http://www.maltblue.com/tutorial/use-zend-framework-2-routematch-for-dynamic-routing/attachment/set-results-per-page" rel="attachment wp-att-12217"><img
class="size-medium wp-image-12217 alignnone" alt="Custom Zend Framework 2 ViewHelper with Paginated List - Set Results Per Page" src="http://www.maltblue.com/wp-content/uploads/2013/05/set-results-per-page-300x106.png" width="300" height="106" /></a></p><p>At first I tried a rather convoluted function that used <a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction">the EventManager</a> in ZF2. To say the least, it was long and convoluted. Then I came across a post from Sam Minds that lead me to the eventual solution I present here today.</p><p>It turned out to be so simple, that I can keep adding further route options and the code stay&#8217;s pretty small. And to do it, all I needed was 3 components from the new Zend Framework 2:</p><ol><li><a
href="http://framework.zend.com/apidoc/2.0/classes/Zend.Mvc.Router.Http.TreeRouteStack.html">Zend\Mvc\Router\Http\TreeRouteStack</a></li><li><a
href="http://framework.zend.com/apidoc/2.1/classes/Zend.Http.Request.html">Zend\Http\Request</a></li><li><a
href="http://framework.zend.com/apidoc/2.0/classes/Zend.Mvc.Router.Http.RouteMatch.html">Zend\Mvc\Router\Http\RouteMatch</a></li></ol><p>The key component though, is <strong>RouteMatch</strong>. If you&#8217;re not familiar with it, it looks as follows:</p><pre>namespace Zend\Mvc\Router;
class RouteMatch
{
    public function __construct(array $params);
    public function setMatchedRouteName($name);
    public function getMatchedRouteName();
    public function setParam($name, $value);
    public function getParams();
    public function getParam($name, $default = null);
}
</pre><p>What it does is allow you to set and extract parameters from a given Route object, in my case, the current one. Even better, I only needed to use 3 functions. These are:</p><ul><li><strong>getMatchedRouteName</strong></li><li><strong>getParam</strong></li><li><strong>setParam</strong></li></ul><p>I&#8217;ll skip from the story now and show you the code, so you can see what I did. In the code below, you can see a part of my <strong>getViewHelperConfig</strong> definition in the module&#8217;s <strong>Module.php</strong> file. Here, I&#8217;ve use the <strong>factories</strong> element to initialise my new ViewHelper, passing in the Router and Request objects retrieved <a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager">from the ServiceManager</a>.</p><p>This gives me access to the core of the information that I need about both the current route and request.</p><pre>namespace MaltBlue;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use MaltBlue\View\Helper\ListViewToolbar;
class Module
{
    public function getViewHelperConfig()
    {
        return array(
            'factories' =&gt; array(
                'listViewToolbar' =&gt; function($sm) {
                    $locator = $sm-&gt;getServiceLocator();
                    return new ListViewToolbar(
                      $locator-&gt;get('Router'), $locator-&gt;get('Request')
                    );
                },
            ),
        );
    }
}
</pre><p>In the constructor of the ViewHelper, I initialise two class variables with the Router and Request objects obtained.</p><pre>namespace CoalescentCore\View\Helper;
use Zend\View\Helper\AbstractHelper;
use Zend\Mvc\Router\Http\TreeRouteStack as Router;
use Zend\Http\Request;
use Zend\Mvc\Router\Http\RouteMatch;
class ListViewToolbar extends AbstractHelper
{
    protected $router;
    protected $request;
    protected $viewTemplate;
    protected $allowedFilters;
    public function __construct(Router $router, Request $request)
    {
        $this-&gt;router = $router;
        $this-&gt;request = $request;
        $this-&gt;viewTemplate = "/toolbar/listview";
    }
</pre><p>Next I have a method <strong>_getFilterRoute</strong>. This is responsible for determining and setting the record status filter in the route. First I initialise a RouteMatch object, by calling <strong>match</strong> on the Router object and pass in the Request object.</p><p>If the statusFilter supplied is in an allowed list (currently a simply array) I set the status route parameter to the value supplied.</p><p>After that, I then assemble a new route, by calling the <strong>assemble</strong> function on the router object. I pass to assemble the complete, updated, list of route parameters (the previous list with the one change that I&#8217;ve just made) &#8211; along with the route name, retrieved with the <strong>getMatchedRouteName</strong> function. From this the function returns a fully formed Url.</p><pre>
    protected function _getFilterRoute($statusFilter = 'all')
    {
        $routeMatch = $this-&gt;router-&gt;match($this-&gt;request);
        if (in_array($statusFilter, $this-&gt;allowedFilters)) {
            $routeMatch-&gt;setParam('status', $statusFilter);
        } else {
            $routeMatch-&gt;setParam('status', 'all');
        }
        return $this-&gt;router-&gt;assemble(
            $routeMatch-&gt;getParams(),
            array('name' =&gt; $routeMatch-&gt;getMatchedRouteName())
        );
    }
</pre><p>Finally, in the <strong>__invoke</strong> method, the returned Url is passed as the value of a view parameter, <strong>activeFilterLink</strong>, and the rendered view template is returned.</p><pre>
    public function __invoke($searchPlaceholder, $newItemName, $newItemRoute)
    {
        return $this-&gt;getView()-&gt;render($this-&gt;viewTemplate, array(
            'activeFilterLink' =&gt; $this-&gt;_getFilterRoute(
               $statusFilter = 'active'
            ),
        ));
    }
</pre><div
class="author-box">NB: I don&#8217;t have too much space today to cover custom ViewHelpers, sorry. But have a look at <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.view.helpers.advanced-usage.html">the great online documentation</a> to find out more.</div><p>So now, using a limited amount of custom code combined with the right objects and methods available in Zend Framework 2 and I can dynamically adjust an existing route on the fly.  One last thing &#8211; the code sample will be up on the <a
href="https://github.com/maltblue" title="Malt Blue Github Repository">Malt Blue Github repository</a> soon. Just need a bit more time.</p><h2>Over To You</h2><p>What do you think? Have you encountered a situation that could do with the solution presented in today&#8217;s post? Is there a simpler way that I&#8217;m overlooking (or haven&#8217;t learned yet)? Tell me today &#8211; share your thoughts, ideas and opinion in the comments!</p><h2>Need help learning Zend Framework 2?</h2><p>If you need a hand learning this amazing framework &#8211; you&#8217;re in luck. I&#8217;m actively working on a new Zend Framework 2 book, called <strong>Zend Framework 2 &#8211; For Beginners</strong>. <a
title="Zend Framework 2 For Beginners" href="https://leanpub.com/zendframework2-for-beginners">Sign up today</a> and be notified as soon as it&#8217;s ready. Plus &#8211; <em>get samples and spoilers while you wait</em>.</p><p>image copyright <a
href="http://flic.kr/p/9Vd7EL" title="image copyright idvsolutions">idvsolutions</a></p><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-12119" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/zf2-eventmanager-feature-image-resized-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 ServiceManager &#8211; Web Application Development Simplified" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" class="wp_rp_title">Zend Framework 2 ServiceManager &#8211; Web Application Development Simplified</a></li><li
data-position="1" data-poid="in-12103" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Event Manager &#8211; A Gentle Introduction" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" class="wp_rp_title">Zend Framework 2 Event Manager &#8211; A Gentle Introduction</a></li><li
data-position="2" data-poid="in-12061" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/Post-Image-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Modules &#8211; The Application&#8217;s Heart" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_title">Zend Framework 2 Modules &#8211; The Application&#8217;s Heart</a></li><li
data-position="3" data-poid="in-9041" ><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-1-custom-filter-paths" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form Mastery with Zend Config &#8211; Part 1 Custom Filter Paths" title="" /></a><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-1-custom-filter-paths" class="wp_rp_title">Zend Form Mastery with Zend Config &#8211; Part 1 Custom Filter Paths</a></li><li
data-position="4" data-poid="in-11001" ><a
href="http://www.maltblue.com/tutorial/how-to-make-zend-forms-available-in-all-modules-in-just-one-step" class="wp_rp_thumbnail"><img
width="150" height="112" src="http://www.maltblue.com/wp-content/uploads/2012/08/6390464879_1cdefc34af.jpg" class="attachment-thumbnail wp-post-image" alt="How to Use the Zend Form ViewScript Decorator In All Modules" title="" /></a><a
href="http://www.maltblue.com/tutorial/how-to-make-zend-forms-available-in-all-modules-in-just-one-step" class="wp_rp_title">How to Use the Zend Form ViewScript Decorator In All Modules</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=OakT3uvDEqA:FtuRl1doGAY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=OakT3uvDEqA:FtuRl1doGAY:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=OakT3uvDEqA:FtuRl1doGAY:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=OakT3uvDEqA:FtuRl1doGAY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=OakT3uvDEqA:FtuRl1doGAY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=OakT3uvDEqA:FtuRl1doGAY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=OakT3uvDEqA:FtuRl1doGAY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=OakT3uvDEqA:FtuRl1doGAY:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=OakT3uvDEqA:FtuRl1doGAY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=OakT3uvDEqA:FtuRl1doGAY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=OakT3uvDEqA:FtuRl1doGAY:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/OakT3uvDEqA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/tutorial/use-zend-framework-2-routematch-for-dynamic-routing/feed</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://www.maltblue.com/tutorial/use-zend-framework-2-routematch-for-dynamic-routing</feedburner:origLink></item> <item><title>Why Testing Makes a Project Successful and You Can’t Afford to Deny It</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/Wn0Jj-b054s/why-successful-software-includes-testing</link> <comments>http://www.maltblue.com/software-development/testing/why-successful-software-includes-testing#comments</comments> <pubDate>Tue, 23 Apr 2013 09:21:11 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Testing]]></category> <category><![CDATA[cloud development]]></category> <category><![CDATA[personal efficiency]]></category> <category><![CDATA[software engineering]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12199</guid> <description><![CDATA[Did you know  software developers spend 50% of their programming time finding and fixing bugs costing the global economy $312 billion per year? You don't have to be one of them. ]]></description> <content:encoded><![CDATA[<p><a
href="http://www.maltblue.com/software-development/testing/why-successful-software-includes-testing/attachment/8217500068_8e92c4c791_n" rel="attachment wp-att-12205"><img
class="alignright size-full wp-image-12205" style="margin: 0px 0px 5px 5px" alt="software testing is essential" src="http://www.maltblue.com/wp-content/uploads/2013/04/8217500068_8e92c4c791_n.jpg" width="320" height="240" /></a> According to <a
href="prweb.com">prweb.com</a>, recent Cambridge University research found that, on average, software developers spend <strong>50% of their programming time finding and fixing bugs</strong> and estimate that this costs the global economy <strong>$312 billion per year</strong>.</p><h2>Don&#8217;t be part of that statistic</h2><p>Like many of us, despite being told repeatedly how great testing is, the benefits it will bring, the time it will save and how it will improve the quality of my applications, I too considered testing a second-thought.</p><p>I saw it as something which was both expensive and time-consuming. If I was genuine with you, I&#8217;d say I believed it be be nothing more than a &#8220;nice to have&#8221;, after the application was written. If you also feel (or have felt) this way &#8211; know that <strong>you&#8217;re not alone</strong>.</p><p>What made it even more difficult for me, was hearing people regularly reinforcing these false and ultimately costly assumptions and beliefs. I&#8217;d start to get excited about it, only to hear a variety of the following phrases:</p><ul><li>Testing is too expensive</li><li>Testing is too time consuming</li><li>It&#8217;s too difficult</li><li>It will take time away from <em>real</em> development</li><li>The client&#8217;s not prepared to pay for it</li></ul><p>So, possibly sadly, it&#8217;s only in recent times that I&#8217;ve started getting involved with <a
href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a>, <a
href="http://en.wikipedia.org/wiki/Behavior-driven_development">BDD</a> and related techniques.</p><p>But it&#8217;s never too late to begin!</p><div
class="author-box"><strong>Quick Task:</strong> How many of the above 5 have you heard or said and when was the last time? I&#8217;m keen to get your thoughts in the comments. That way we can have an informed discussion. Please stop a moment and add your thoughts. Then come on back here and let&#8217;s continue.</div><h2> Testing Can&#8217;t Be an After-Thought</h2><p>It&#8217;s treated as an after thought, a nice to have, an academic or utopian ideal that really can&#8217;t or doesn&#8217;t exist in <strong>the real world</strong>. Yet people wonder why projects <em>regularly</em> over-run both on cost and time and countless hours are spent bug fixing. The net result is we have a botched reputation and the joy of development saps away somewhere to die.</p><p>However, what&#8217;s reassuring to me is that the more I look around recently, the more projects I see that have testing not only as a serious going concern, but as an <strong>integral part of the development mindset</strong>.</p><p>As a result it becomes a natural part of the development process. It becomes integrally interwoven in the mindset of the application. If you&#8217;ve not seen them, here&#8217;s a small selection:</p><ul><li>Zend Framework 2 (integrated PHPUnit and Zend Test)</li><li>jQuery &amp; Node (Mocha, QUnit, should.js, expect.js, chai, better-assert)</li><li>Grunt</li><li>Silex</li><li>Symfony</li></ul><h2>But It&#8217;s Not Always Easy</h2><p>If you&#8217;re on <a
href="http://eepurl.com/dWhRf">the Malt Blue mailing list</a>, you&#8217;ll know that recently I&#8217;ve undertaken a new Zend Framework 2 based project. In that project, I&#8217;ve been determined to correct my bad development habits and really take on a <em>test-centric approach</em> to development.</p><p>But as the saying goes <em>the road to hell is paved with good intentions</em>. And so it seemed at first with the project. There I sat, all excited to be <em>testing, testing, testing</em>. And at first, all seemed well.</p><p>Then it became difficult. I&#8217;d write loads of tests, for a range of components all at once, run the test and be faced with a litany of failures, across a range of different components. I&#8217;d start working through them, find more, fix them, find more and so on.</p><p><a
href="http://www.maltblue.com/software-engineering-2/how-simplicity-leads-to-greater-productivity-quality-and-satisfaction">In the last post</a> here on the blog I expressed my sense of dismay at the stress that was resulting from it all. Luckily, I am fortunate to have a very <strong>educated, wise and calm</strong> testing mentor in the form of a former colleague and friend.</p><p>Through much time, chatting on Skype, he gave clear guidance in how to approach it. I&#8217;ll skip over the full conversation but give you this one gem that he gave me.</p><blockquote><p>Write just enough tests to test the smallest part of functionality, then implement the code and retest until it the tests pass.</p></blockquote><h2>A Simple Test Perspective</h2><p>With that change of perspective, instead of trying to build the controllers, entities/models and related components, I took on a simpler approach, which is painlessly simple to follow. The image below describes it best.</p><p
style="text-align: center"><a
href="http://www.maltblue.com/?attachment_id=12200" rel="attachment wp-att-12200"><img
class="aligncenter  wp-image-12200" alt="simple-testing-diagram" src="http://www.maltblue.com/wp-content/uploads/2013/04/simple-testing-diagram.png" width="541" height="158" /></a></p><p>I decided to just start building entities alone. I began afresh, writing a test first, then adding code to the entity accordingly. <strong>No more, no less</strong>.</p><p>Then, when the entity was complete, I built the form that would use the entity. I wrote tests first, then the coded the form itself. Following this, I built one or two <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.db.table-gateway.html">TableGateway classes</a>, as that&#8217;s what I&#8217;m using (maybe Doctrine on another project).</p><p>This change brought about a rapid escalation in productivity. Doing one thing well, then another, then another, produced great progress.</p><h2>Was it Practically Working?</h2><p>After a while however, I started to doubt the validity of what I was producing. It was great that I had all these tests for the individual components. But how would they go when they were bound together later on.</p><p>With a pressing deadline, I was rather concerned that maybe I was in the grip of an engrossing illusion. I held fast, thinking that no, this was a new path, one I&#8217;d not trodden down much before. I can&#8217;t just stop because I feel slightly uncomfortable or unsure.</p><p>But later the concern returned. So this time, I put the testing on pause and thought:</p><blockquote><p>I&#8217;ll put one entity, form and table gateway together and just see how it goes</p></blockquote><p>So, using <a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager">the wonderful ZF2 service manager</a> (for sakes of simplicity), I did just that.</p><p>I can&#8217;t express the amount of relief, joy, happiness and satisfaction I felt as I looked at what was rendered in the browser and how it operated. It <strong>100% matched</strong> the mocked world of the tests which I&#8217;d been creating.</p><p>One fear still remained though:</p><blockquote><p>Was the application development time, in some way increased, because of the time spent writing the tests?</p></blockquote><p>In answer to you, initially it felt and still does in part, feels that way. But I believe I&#8217;m seeing a better placement of effort. I like to compare it to the anecdotal experiences of Windows and Linux systems administrators.</p><p>With Windows, you can seemingly get a system up and running quickly, but may spend a lot of time with it later. With Linux (and speaking from personal experience), you may spend a lot of time at first, doing a lot of things, but when it&#8217;s done, it&#8217;s done.</p><p>Just leave it, monitor it occasionally and it will just keep on humming. Now no, this isn&#8217;t a true and accurate reflection of reality, but the sentiment is correct. My experience can be summed up in one word.</p><h2>Confidence</h2><ul><li>Confidence that what I&#8217;ve made works as intended</li><li>Confidence that when code is shipped it will work</li><li>Confidence that the time spent in development, is not wasted (or just a downpayment on time to be spent later)</li></ul><p>There&#8217;s phrase that also fits &#8211; <strong>Peace Of Mind</strong>.</p><p>When we&#8217;re working for others, but especially more so when <a
href="http://www.maltblue.com/contact">we&#8217;re private freelancers</a>, both us and our clients need peace of mind. If you aren&#8217;t confident that your code works (arrogance is no compensation), then how can we be sure what we give to our clients works?</p><p>How do we know that they won&#8217;t ring us up in the middle of the night, days, weeks or months later with a &#8220;<em>seemingly random</em>&#8221; bug. How do we know that the relationship that is so important, will grow and prosper.</p><p>In short, how can we rest assured that when we believe we&#8217;re finished (and grab that beer) that we <strong>actually are? </strong>I hear the questions coming already:</p><ul><li>What if you haven&#8217;t tested everything?</li><li>What if the tests you wrote are wrong?</li><li>What if you didn&#8217;t&#8217; think of certain edge cases?</li></ul><p>These are all valid questions, each and every one. And they will all happen from time to time. But the key take away from this article, is that at least by having tests, we&#8217;re in a much stronger position. If we find bugs, we add in regression tests, fix the error and move on, having tests in place to catch that.</p><h2>Balance</h2><p>This leads me to the last part of today&#8217;s post &#8211; balance. Testing can be just like a shiny toy. Once we have it, we want to do everything possible with it. So much so that we spend more time writing tests, even for situations where it&#8217;s not necessary to have them.</p><p>So, whilst I&#8217;ll be writing more about testing from now on. I encourage you to maintain a sense of balance. Integrate testing as an essential part of your development mentality and process &#8211; but don&#8217;t get carried away.</p><p>Do what you need first, then gradually build over time. With time and experience, you&#8217;ll find a natural level that suits both you and your specific project.</p><h2>Over to you</h2><p>So I&#8217;ve told my story and hope I&#8217;ve convinced you why testing won&#8217;t cost, but will save you time, stress and money. Tell me your story. What is it like in your organisation, your team, your job? Is testing taken seriously, is it integral to the development process, how much time does it save you. Share your thoughts in the comments.</p><h2>Need Help?</h2><p>If you&#8217;re new to testing, unsure about how to get started or the best approach to take, email me today. Better yet, Skype me. I want to help you integrate testing in to your applications, so that you&#8217;ll see the same productivity gains that I have. You won&#8217;t know yourself when you do.</p><p>image credit: <a
title="image credit - thefangmonster" href="http://flic.kr/p/dw9QtE">thefangmonster</a></p><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-2341" ><a
href="http://www.maltblue.com/methodology/hassle-free-software-development" class="wp_rp_thumbnail"><img
width="123" height="150" src="http://www.maltblue.com/wp-content/uploads/2011/09/stress-kit.jpg" class="attachment-thumbnail wp-post-image" alt="Hassle Free Software Development" title="" /></a><a
href="http://www.maltblue.com/methodology/hassle-free-software-development" class="wp_rp_title">Hassle Free Software Development</a></li><li
data-position="1" data-poid="in-1048" ><a
href="http://www.maltblue.com/php/php-needs-better-beginners" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2011/05/4942572797_898ec7ec75-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="PHP Needs Better Beginners" title="" /></a><a
href="http://www.maltblue.com/php/php-needs-better-beginners" class="wp_rp_title">PHP Needs Better Beginners</a></li><li
data-position="2" data-poid="in-8921" ><a
href="http://www.maltblue.com/deployment-2/reflections-on-php-application-deployment-1-more" class="wp_rp_thumbnail"><img
width="150" height="92" src="http://www.maltblue.com/wp-content/uploads/2012/02/6273248505_c47f7c76d1.jpg" class="attachment-thumbnail wp-post-image" alt="Reflections on PHP Application Deployment + 1 More" title="" /></a><a
href="http://www.maltblue.com/deployment-2/reflections-on-php-application-deployment-1-more" class="wp_rp_title">Reflections on PHP Application Deployment + 1 More</a></li><li
data-position="3" data-poid="in-68" ><a
href="http://www.maltblue.com/software-development/do-you-know-how-to-talk-to-a-developer-really" class="wp_rp_thumbnail"><img
src="http://www.maltblue.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/26.jpg" alt="Do you REALLY know how to talk to your development team?" /></a><a
href="http://www.maltblue.com/software-development/do-you-know-how-to-talk-to-a-developer-really" class="wp_rp_title">Do you REALLY know how to talk to your development team?</a></li><li
data-position="4" data-poid="in-374" ><a
href="http://www.maltblue.com/organisation/being-organised-helps-you-work-best" class="wp_rp_thumbnail"><img
src="http://www.maltblue.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/15.jpg" alt="Being Organised helps you work Best!" /></a><a
href="http://www.maltblue.com/organisation/being-organised-helps-you-work-best" class="wp_rp_title">Being Organised helps you work Best!</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=Wn0Jj-b054s:J3h5MEEVKpk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=Wn0Jj-b054s:J3h5MEEVKpk:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=Wn0Jj-b054s:J3h5MEEVKpk:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=Wn0Jj-b054s:J3h5MEEVKpk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=Wn0Jj-b054s:J3h5MEEVKpk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=Wn0Jj-b054s:J3h5MEEVKpk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=Wn0Jj-b054s:J3h5MEEVKpk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=Wn0Jj-b054s:J3h5MEEVKpk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=Wn0Jj-b054s:J3h5MEEVKpk:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=Wn0Jj-b054s:J3h5MEEVKpk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=Wn0Jj-b054s:J3h5MEEVKpk:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/Wn0Jj-b054s" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/software-development/testing/why-successful-software-includes-testing/feed</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://www.maltblue.com/software-development/testing/why-successful-software-includes-testing</feedburner:origLink></item> <item><title>How Simplicity Leads to Greater: Productivity, Quality &amp; Satisfaction</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/LEA1q_1sKVc/how-simplicity-leads-to-greater-productivity-quality-and-satisfaction</link> <comments>http://www.maltblue.com/software-engineering-2/how-simplicity-leads-to-greater-productivity-quality-and-satisfaction#comments</comments> <pubDate>Tue, 16 Apr 2013 08:00:32 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Software Engineering]]></category> <category><![CDATA[development]]></category> <category><![CDATA[personal efficiency]]></category> <category><![CDATA[software development]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12189</guid> <description><![CDATA[Though we can do so many things simultaneously - should we? Does it actually reduce effectiveness and productivity which are the antithesis of professional application development? Let's discuss.]]></description> <content:encoded><![CDATA[<p>Though we <em>can</em> do so many things simultaneously &#8211; should we? Does it actually reduce effectiveness and productivity which are the antithesis of professional application development? Let&#8217;s discuss.</p><h2>More Work != More Productivity (and Satisfaction)</h2><p>Recently, I&#8217;ve felt rather under the pump to get through a series of client projects (lucky me you may say). There has been a lot to do, to organise, to plan and, ultimately to balance.</p><p>Whilst I&#8217;ve been a web application developer for over 12 years, I still found myself feeling overwhelmed and eventually having to deal with anxiety and stress, which if left unattended may have lead to burnout.</p><p>I had the thought, as is common in a western-based mentality, that to be busy, to be industrious, to try and multi-task a series of independent tasks and projects simultaneously was <em>the right thing to do</em>. It&#8217;s meant to be a simple formula:</p><pre>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Greater productivity = Greater self-worth right?</div></td></tr></tbody></table></div>
</pre><p>Sounds almost like <a
href="http://en.wikipedia.org/wiki/Thatcherism">Thatcherism</a>.</p><p>I felt that this was not only right, but the sign of an intelligent and sophisticated developer, <strong>who truly had honed his craft</strong>. Perhaps you&#8217;ve felt the same at one time or another?</p><p>How about this &#8211; have you been offered an enticing project? One that gives you the ability to expand your knowledge of the subject matter (such as <em>accounting</em>, <em>advertising</em> or <em>physics</em>); one that challenges you to create a rather sophisticated and intelligent design, ultimately resulting in a very remarkable application for the client or organisation?</p><p>I&#8217;m sure, if you&#8217;re anything like me, you have and that it set your mind racing. You thought:</p><blockquote><p>&#8220;I&#8217;ll create it around a set of modules. Those modules will have a set of sub-interdependent parts, which will intern interact seamlessly with related, external, services &#8211; and it will be <strong>AMAZING</strong>&#8220;.</p></blockquote><p>Well, that was me. I did just that. This excitement, lead me to try do <strong>everything all at once</strong>. I was trying to create tests for forms, entities, controllers all at once.</p><p>However, instead of brilliance, this resulted in extreme stress and anxiety as well as a substantial workload. As a result I decided to stop, think and ultimately take a different approach. If this was the first time, I may well not have.</p><h2>The New Approach</h2><p>It takes many forms, but said most succinctly, it&#8217;s an idea that I&#8217;m sure you&#8217;re heard at least one time: <strong>K</strong>eep <strong>I</strong>t <strong>S</strong>imple <strong>S</strong>illy. Yes, <strong><acronym
title="Keep it simple, stupid">KISS</acronym></strong>.</p><p>Instead of trying to do everything at once &#8211; I stopped and decided to only do <strong>one thing at once</strong>. And that one thing, had my full attention and focus. When it was done, I then moved on to the next one. Not before <em>and not after</em>.</p><p>Why? Well have you heard the answer to the question &#8211; How do you eat an Elephant? If not here it is &#8211; <strong>one bite at a time</strong>.</p><h2>Will It Work</h2><p>At this stage, I&#8217;m not sure how this new approach will go. But I&#8217;m hopeful of what the results may be. The best thing is, one of my active projects will be acting as a test subject. So I&#8217;ll get to see how it goes.</p><p>As a bit of background &#8211; it&#8217;s <a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection">a Zend Framework 2 based project</a>. Whilst it&#8217;s not, technically, that complex, the amount of <em>forms</em>, <em>entities</em>, <em>validators</em>, <em>filters</em>, <em>modules</em>, <em>controllers</em>, <em>actions</em> and <em>relationships</em> within the components of the application, make it both complex and time intensive to complete.</p><p><strong>As an aside:</strong> I&#8217;m confident that a good use of <a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart">the Module Manager</a> and <a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager">Service Manager</a> in zf2 will help make code easier to write and more maintainable. I&#8217;ll be blogging on the results, as well as how using <em>database views</em> reduces application complexity, over the coming weeks.</p><p>For the remainder of this project I will be following this new motto &#8211; doing one task at a time and doing it well. No more, no less. This doesn&#8217;t reduce the workload, but it should make it easier to manage.</p><p>I&#8217;m hoping that it will not only produce a better result than my previous approach and also one that will result in more <em>satisfaction</em>, <em>less stress</em>, and overall a<em> better work/life balance</em> &#8211; along with a happy client.</p><h2>Over to you</h2><p>Do you attempt to take on too many projects, or too many tasks, at the one time? Do you believe that results in better developed applications, greater satisfaction and happy clients?</p><p>If you&#8217;re honest with yourself now, is it working for you? Or would a simpler approach be more beneficial?</p><p>I leave this question with you and hope you&#8217;ll give your input today.</p><p>Image credit <a
title="Image credit Irving Lau" href="http://flic.kr/p/arkeg1">Erving_Lau</a></p><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-374" ><a
href="http://www.maltblue.com/organisation/being-organised-helps-you-work-best" class="wp_rp_thumbnail"><img
src="http://www.maltblue.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/15.jpg" alt="Being Organised helps you work Best!" /></a><a
href="http://www.maltblue.com/organisation/being-organised-helps-you-work-best" class="wp_rp_title">Being Organised helps you work Best!</a></li><li
data-position="1" data-poid="in-885" ><a
href="http://www.maltblue.com/software-development/5-pillars-of-successful-software-development" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2011/05/white-board-small-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="The 5 Pillars of Successful Software Development" title="" /></a><a
href="http://www.maltblue.com/software-development/5-pillars-of-successful-software-development" class="wp_rp_title">The 5 Pillars of Successful Software Development</a></li><li
data-position="2" data-poid="in-1160" ><a
href="http://www.maltblue.com/documentation/5-examples-of-good-developerdocumentation" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2011/06/cornerstone-documentation-short-150x150.png" class="attachment-thumbnail" alt="cornerstone-documentation-short" /></a><a
href="http://www.maltblue.com/documentation/5-examples-of-good-developerdocumentation" class="wp_rp_title">5 examples of good developer documentation</a></li><li
data-position="3" data-poid="in-284" ><a
href="http://www.maltblue.com/zend-framework/writing-a-secure-restful-service-in-the-zend-framework-part-2" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Writing a secure, RESTful service in the Zend Framework, Part 2" title="" /></a><a
href="http://www.maltblue.com/zend-framework/writing-a-secure-restful-service-in-the-zend-framework-part-2" class="wp_rp_title">Writing a secure, RESTful service in the Zend Framework, Part 2</a></li><li
data-position="4" data-poid="in-12145" ><a
href="http://www.maltblue.com/software-engineering-2/5-reaons-coding-standards-are-essential" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/03/8230432077_e7c4d5ff40-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="5 Reasons Coding Standards Are Essential" title="" /></a><a
href="http://www.maltblue.com/software-engineering-2/5-reaons-coding-standards-are-essential" class="wp_rp_title">5 Reasons Coding Standards Are Essential</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=LEA1q_1sKVc:IdMJDsnhHGg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=LEA1q_1sKVc:IdMJDsnhHGg:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=LEA1q_1sKVc:IdMJDsnhHGg:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=LEA1q_1sKVc:IdMJDsnhHGg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=LEA1q_1sKVc:IdMJDsnhHGg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=LEA1q_1sKVc:IdMJDsnhHGg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=LEA1q_1sKVc:IdMJDsnhHGg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=LEA1q_1sKVc:IdMJDsnhHGg:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=LEA1q_1sKVc:IdMJDsnhHGg:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=LEA1q_1sKVc:IdMJDsnhHGg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=LEA1q_1sKVc:IdMJDsnhHGg:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/LEA1q_1sKVc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/software-engineering-2/how-simplicity-leads-to-greater-productivity-quality-and-satisfaction/feed</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.maltblue.com/software-engineering-2/how-simplicity-leads-to-greater-productivity-quality-and-satisfaction</feedburner:origLink></item> <item><title>Zend Framework 2 Forms – Simple and Available Everywhere</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/01FjN3UulZ8/simple-zend-framework-2-forms</link> <comments>http://www.maltblue.com/zend-framework/simple-zend-framework-2-forms#comments</comments> <pubDate>Thu, 04 Apr 2013 02:51:17 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[Zend Framework]]></category> <category><![CDATA[Zend Form]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12177</guid> <description><![CDATA[In Zend Framework 2, so much has been changed, updated and improved - with Forms receiving a lot of attention. In this post, I show you a simple, flexible and powerful approach to compose and use them everywhere in your applications.]]></description> <content:encoded><![CDATA[<p>I think it goes without saying, forms are one of the central elements of any web-based application. They&#8217;re used for everything from logging in, to searching content and managing information. Given that, they should be first-class citizens, able to be developed and reused with relative ease.</p><p>I know for myself, on the web application projects which <a
href="http://www.maltblue.com">Malt Blue</a> is currently undertaking, I need to be able to develop them as quickly and flexibly as possible, to help ensure project budgets and timelines are not overrun.</p><p>However, given the amount of <em>options</em>, <em>configurability</em> and <em>flexibility</em> required, this isn&#8217;t always easy. With Zend Framework 2, I believe the contributors have made some very worthy improvements, which help forms become the first class citizens they need to be.</p><p>In today&#8217;s post, I&#8217;m going to assume you have a basic understanding of how <a
href="http://framework.zend.com/manual/2.1/en/modules/zend.form.intro.html">forms</a> work now. So if I skip over any aspect of theory you&#8217;re not familiar with, there will be a number of links in <a
href="#further_reading">the further reading section</a> to help you.</p><p>I&#8217;m going to show you how to create flexible, reusable forms in one module and by the power of the ServiceManager reuse them throughout your application. Sound fun? Great. <strong>Let&#8217;s get started.</strong></p><h2>Setting Up Dependencies</h2><p>One thing I need to mention is, though quite subtly, the form that we&#8217;re creating will be extending the ProvidesEventsForm class provided in ZfcBase. The simplest way to get it is to make it available is via ZfcUser in Composer. So, in your project&#8217;s <strong>composer.json</strong> file, add the following:</p><pre>"require": {
    ...
    "zf-commons/zfc-user": "dev-master",
    ...
}
</pre><p>Then run the following to bring in the module to your vendor directory:</p><pre>composer update
</pre><p>Under the vendor directory, you will have a new directory, <strong>zf-commons</strong> and under it, two directories: <strong>zfc-base</strong> and <strong>zfc-user</strong>. Enable ZfcBase in your application by adding <strong>&#8216;ZfcBase&#8217;</strong> to the modules section of your <strong>config/application.config.php</strong> file. We now have all of the dependencies we need.</p><h2>Creating the Reusable Module</h2><p>The first thing we need to do is to create our new module. For simple nomenclature, let&#8217;s call it <strong>ContentCore</strong>. Whether by hand or with the assistance of ZF Tool, create a new module with the following structure:</p><ul><li>ContentCore<ul><li>config<ul><li>module.config.php</li></ul></li><li>src<ul><li>ContentCore<ul><li>Entity<ul><li>User.php</li></ul></li><li>Form<ul><li>UserFieldset.php</li><li>CreateUser.php</li></ul></li></ul></li></ul></li><li>Module.php</li></ul></li></ul><p>This structure provides <a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart">the basic requirements of a module</a>, which are the Module.php file and the config/module.config.php file. Then we have the User class under <strong>Entity</strong> and two further files under <strong>Form</strong>.</p><p>I&#8217;ve skipped along a bit here; but what we&#8217;re going to do is to do minimal work in each section. The form will provide the form infrastructure, along with a submit button and CSRF security field.</p><p>The UserFieldset will handle rendering the Entity elements, stipulating the <em>field types</em>, <em>options</em> and <em>validation rules</em>. Finally, the Entity class will store the information passed through to the form by the user. Let&#8217;s now get in to the nitty gritty of each one.</p><h2>The Entity Class</h2><p>The entity class allows us to model and manipulate information the object requires. As you can see below, it has three properties:</p><ul><li>UserId</li><li>firstName</li><li>lastName</li></ul><p>It&#8217;s fair to say this object can be mapped to a record in a database, but it needn&#8217;t be. It has two methods:</p><ul><li>exchangeArray</li><li>getFullName</li></ul><p>exchangeArray allows data from an external source to be mapped to the internal properties of the object. getFullName returns the full name of the user, like a contact list would, i.e., first name then last name or vice versa.</p><pre>namespace ContentCore\Entity;
class User
{
    CONST DISPLAY_NAME_FIRSTLAST = "firstLast";
    CONST DISPLAY_NAME_LASTFIRST = "lastFirst";
    public $UserId;
    public $firstName;
    public $lastName;
    public function exchangeArray($data)
    {
        $this-&gt;UserId = (isset($data['UserId'])) ? $data['UserId'] : null;
        $this-&gt;firstName = (isset($data['FirstName'])) ? $data['FirstName'] : null;
        $this-&gt;lastName = (isset($data['LastName'])) ? $data['LastName'] : null;
    }
    public function getFullName($displayOrder = self::DISPLAY_NAME_FIRSTLAST)
    {
        if ($displayOrder === self::DISPLAY_NAME_FIRSTLAST) {
            return sprintf("%s %s", $this-&gt;firstName, $this-&gt;lastName);
        } else {
            return sprintf("%s %s", $this-&gt;lastName, $this-&gt;firstName);
        }
    }
}
</pre><p>Overall, nothing too difficult here.</p><h2>The Fieldset Class</h2><p>In the UserFieldset class, it gets a bit more difficult. Fieldsets are a way of grouping logically related elements and being able to dynamically share them between different forms.</p><p>The <strong>setObject</strong> method is used so the fieldset can extract from and set information supplied in the User object we just talked about. The setHydrator method, receiving the <strong>ObjectPropertyHydrator</strong> object is used to work with the User object.</p><p>If you&#8217;re not familiar with Hydrators, the <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.stdlib.hydrator.html">Zend Framework 2 manual</a> describes hydration as:</p><blockquote><p>Hydration is the act of populating an object from a set of data.</p></blockquote><p>There are a number of hydrators available. The ObjectPropertyHydrator is able to look at the properties of the entity provided, to know which values to populate in the form. I used this one to avoid writing specific methods.</p><p>Consequently, the entity properties and the form field element names need to match up. Your approach may differ. I&#8217;ll work through the class a bit more now.</p><pre>use ContentCore\Entity\User;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Stdlib\Hydrator\ObjectProperty as ObjectPropertyHydrator;
class UserFieldset extends Fieldset
    implements InputFilterProviderInterface
{
    public function __construct()
    {
        parent::__construct('User');
        $this-&gt;setHydrator(new ObjectPropertyHydrator(false))
             -&gt;setObject(new User());
</pre><p>This sets the label in the fieldset element.</p><pre>        $this-&gt;setLabel('User');
</pre><p>Here we add two elements to the fieldset, specifying the <em>name</em>, <em>options</em> and <em>attributes</em>. As we&#8217;ve not set a specific type, the element will be rendered as a standard text field. If you want, specify any other in-built or custom one you like. Have a look under <strong>Zend\Form\Element</strong> for the in-built options available.</p><pre>        $this-&gt;add(array(
            'name' =&gt; 'firstName',
            'options' =&gt; array(
                'label' =&gt; 'User\'s First Name'
            ),
            'attributes' =&gt; array(
                'required' =&gt; 'required'
            )
        ));
        $this-&gt;add(array(
            'name' =&gt; 'lastName',
            'options' =&gt; array(
                'label' =&gt; 'User\'s Last Name'
            ),
            'attributes' =&gt; array(
                'required' =&gt; 'required'
            )
        ));
    }
</pre><p>As the class implements <strong>InputFilterProviderInterface</strong>, it needs to implement the <strong>getInputFilterSpecification</strong> method. This specifies the validation rules for the fieldset.</p><p>I&#8217;ve just kept these relatively simple. However, you could get quite complex if you like. You can see all I&#8217;ve specified are that both the firstName and lastName fields are required. What other options would you consider specifying?</p><pre>    /**
     * @return array
     */
    public function getInputFilterSpecification()
    {
        return array(
            'firstName' =&gt; array(
                'required' =&gt; true,
            ),
            'lastName' =&gt; array(
                'required' =&gt; true,
            )
        );
    }
}
</pre><h2>The User Form</h2><p>Now unless it&#8217;s not clear so far, it should become so rather quickly. The reason why I&#8217;ve decided to use Fieldsets is because with them, I can group together logically related form elements, along with related requirements for them, then pass them in to any form I create later.</p><p>In building Zend Framework 1 applications, I spent a lot of time with <acronym
title="eXtensible Markup Language">XML</acronym>-based configurations and field groups with the intent of doing this. But to be honest, it was all rather a lot of overhead and work. Forms in Zend Framework 2 make this tremendously simpler.</p><pre>use Zend\Form\Form;
use Zend\Form\Element;
use ZfcBase\Form\ProvidesEventsForm;
use Zend\InputFilter\InputFilter;
use Zend\Stdlib\Hydrator\ObjectProperty as ObjectPropertyHydrator;
</pre><p>Though I&#8217;ve not done anything with it, my CreateUser form extends <a
href="https://github.com/ZF-Commons/ZfcBase/blob/master/src/ZfcBase/Form/ProvidesEventsForm.php">ProvidesEventsForm</a> from the <a
href="https://github.com/ZF-Commons/ZfcBase">ZfcBase module</a> by Evan Coury.</p><p>This sets up a form so it&#8217;s <a
href="www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction">EventManager aware</a>. Other objects can now register to respond to events this form can trigger during its lifecycle. Perhaps you might want to send a tweet or email after information has been saved or updated?</p><pre>class CreateUser extends ProvidesEventsForm
{
    public function __construct()
    {
        parent::__construct('User');
        $this-&gt;setAttribute('method', 'post')
             -&gt;setHydrator(new ObjectPropertyHydrator(false))
             -&gt;setInputFilter(new InputFilter());
</pre><p>We make the fieldset available to the form, which will render the elements it contains</p><pre>        $this-&gt;add(array(
            'type' =&gt; 'ContentCore\Form\UserFieldset',
            'options' =&gt; array(
                'use_as_base_fieldset' =&gt; true
            )
        ));
</pre><p>As a base form contains no elements by itself, we now add two: a Csrf field and submit button. The Csrf field will contain an auto generated token to ensure the form submission was not spoofed.</p><pre>        $this-&gt;add(array(
            'type' =&gt; 'Zend\Form\Element\Csrf',
            'name' =&gt; 'csrf'
        ));
        $this-&gt;add(array(
            'name' =&gt; 'submit',
            'attributes' =&gt; array(
                'type' =&gt; 'submit',
                'value' =&gt; 'Send'
            )
        ));
    }
}
</pre><p>With that, our form is complete. Now let&#8217;s take it a step further and make the form available anywhere in our application.</p><h2>The Module Configuration</h2><p>Under ContentCore\Module.php, first add the following use statements, so all of the definitions are available.</p><pre>use ContentCore\Entity\User;
use ContentCore\Model\UserTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
</pre><p>Then, in getServiceConfig, add the following definition. What this will do is to make available a key <a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager">in the ServiceManager</a>, which references an instantiated copy of the form we&#8217;ve just setup.</p><pre>public function getServiceConfig()
{
    // ...
    return array(
    'contentuser_create_user_form' =&gt; function($sm) {
        $form = new Form\CreateUser();
        return $form;
    },
    // …
}
</pre><h2>The Application Configuration</h2><p>Now all of this work is nothing, if we don&#8217;t enable the module in the application. So in config/application.config.php, add the following under &#8216;modules&#8217; at the top of the file.</p><pre>'ContentCore',
</pre><h2>The Application Controller Action</h2><p>Right, so now we have our form setup, it&#8217;s available throughout the application via the ServiceManager and the module&#8217;s enabled in our application. Let&#8217;s get about using it in our controller action.</p><p>I created a trivial function <strong>formtestAction</strong>, in the IndexController class which comes with the default Application module to accommodate this.</p><p>You can see below I have three functions and a protected member variable. The member variable will contain the form, just to make things a bit simpler. The _getCreateUserForm function checks if the variable is defined.</p><p>If not, it retrieves a copy of the form <a
href="http://blog.evan.pro/introduction-to-the-zend-framework-2-servicemanager">via the ServiceLocator</a> using the string we defined earlier and calls <em>setCreateUserForm. Otherwise, it returns the form in </em>createUserForm.</p><pre>protected $_createUserForm;
protected function _getCreateUserForm()
{
    if (!$this-&gt;_createUserForm) {
        $this-&gt;_setCreateUserForm(
            $this-&gt;getServiceLocator()-&gt;get('coalescentuser_create_user_form')
        );
    }
    return $this-&gt;_createUserForm;
}
protected function _setCreateUserForm(\Zend\Form\Form $createUserForm)
{
    $this-&gt;_createUserForm = $createUserForm;
}
</pre><p>The last function, formtestAction, calls _getCreateUserForm and binds a new User entity to it. As mentioned earlier, this takes care of retrieving information from and persisting information in the User entity.</p><p>We then check if the request was a post, set form data from the post request information and run the form validation routine. There&#8217;s nothing special here and I&#8217;ve deliberately not fleshed out the steps after a successful validation.</p><p>The action finishes up by returning a ViewModel with one property, our form. This, in my mind, is a lot simpler than the approach Zend Framework 1 Forms took. It requires less code and is simpler to understand. In short, irrespective of the state of the form, one line makes it available to our view template.</p><pre>public function formtestAction()
{
    $form = $this-&gt;_getCreateUserForm();
    $User = new User();
    $form-&gt;bind($User);
    if ($this-&gt;request-&gt;isPost()) {
        $form-&gt;setData($this-&gt;request-&gt;getPost());
        if ($form-&gt;isValid()) {
            // take action
        }
    }
    return new ViewModel(array('form' =&gt; $form));
}
</pre><h2>The View Template</h2><p>Ok, last piece in the puzzle &#8211; the view template. Please make a special note of the <strong>prepare method</strong> call. If you miss this, you&#8217;ll be scratching your head wondering why things <strong>don&#8217;t work</strong>. What this does is to:</p><blockquote><p>ensure validation error messages are available, and prepares any elements and/or fieldsets that require preparation.</p></blockquote><pre>&lt;?php $form-&gt;prepare(); ?&gt;
</pre><p>Next, we use the form helper to open the form, retrieving properties from the form object.</p><pre>&lt;?php echo $this-&gt;form()-&gt;openTag($form); ?&gt;
</pre><p>We then get access to the user fieldset, so we can use the formRow helper to render the elements for the firstName and lastName.</p><pre>&lt;?php $User = $form-&gt;get('User'); ?&gt;
&lt;?php echo $this-&gt;formRow($User-&gt;get('firstName')); ?&gt;
&lt;?php echo $this-&gt;formRow($User-&gt;get('lastName')); ?&gt;
</pre><p>We then finish up by rendering the csrf and submit elements and close the form.</p><pre>&lt;?php echo $this-&gt;formHidden($form-&gt;get('csrf')); ?&gt;
&lt;?php echo $this-&gt;formInput($form-&gt;get('submit')); ?&gt;
&lt;?php echo $this-&gt;form()-&gt;closeTag($form); ?&gt;
</pre><h2>In Conclusion</h2><p>We&#8217;ve now stepped through the process of creating a form, based on an entity which&#8217;s reusable anywhere in our application. I hope you can see forms truly are first class citizens which, combined with the Service Manager, have a tremendous amount of flexibility, configurability and reusability.</p><p>I appreciate it was rather a rapid discussion of the building blocks of the process. So if you need any further information about what was covered here &#8211; let me know in the comments.</p><p>Also, tell me in the comments how you&#8217;re using forms in your Zend Framework 2 applications? What novel and innovative ways are you approaching them?</p><h2><span
id="further_reading">Further Reading</span></h2><ul><li><a
href="http://blog.evan.pro/introduction-to-the-zend-framework-2-servicemanager">The Zend Framework 2 ServiceLocator</a></li><li><a
href="http://framework.zend.com/manual/2.0/en/modules/zend.stdlib.hydrator.html">Zend Framework 2 Hydrators</a></li><li><a
href="http://framework.zend.com/manual/2.1/en/modules/zend.form.intro.html">Zend Framework 2 Forms Introduction</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart">Understanding Zend Framework 2 Modules</a></li><li><a
href="www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction">Understanding the Zend Framework 2 EventManager</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager">Understanding the Zend Framework 2 ServiceManager</a></li></ul><p>featured image, credit <a
href="http://flic.kr/p/63R4Ak" title="image copyright Brian J Bruemmer">Brian J Bruemmer</a></p><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-11142" ><a
href="http://www.maltblue.com/zend-framework/how-to-build-and-extendable-zend-framework-application" class="wp_rp_thumbnail"><img
width="150" height="112" src="http://www.maltblue.com/wp-content/uploads/2012/08/4092702268_39b8c123a6.jpg" class="attachment-thumbnail wp-post-image" alt="How to Build Extendable and Extensible Zend Framework Applications with Custom Resource Plugins" title="" /></a><a
href="http://www.maltblue.com/zend-framework/how-to-build-and-extendable-zend-framework-application" class="wp_rp_title">How to Build Extendable and Extensible Zend Framework Applications with Custom Resource Plugins</a></li><li
data-position="1" data-poid="in-9871" ><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-4-configuring-zend-validators" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form Mastery with Zend Config – Part 4 Configuring Zend Validators" title="" /></a><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-4-configuring-zend-validators" class="wp_rp_title">Zend Form Mastery with Zend Config – Part 4 Configuring Zend Validators</a></li><li
data-position="2" data-poid="in-9041" ><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-1-custom-filter-paths" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form Mastery with Zend Config &#8211; Part 1 Custom Filter Paths" title="" /></a><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-1-custom-filter-paths" class="wp_rp_title">Zend Form Mastery with Zend Config &#8211; Part 1 Custom Filter Paths</a></li><li
data-position="3" data-poid="in-9661" ><a
href="http://www.maltblue.com/php/zend-form-mastery-with-zend-config-part-3-standard-form-element-options" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form Mastery with Zend Config – Part 3 Standard Form &amp; Element Options" title="" /></a><a
href="http://www.maltblue.com/php/zend-form-mastery-with-zend-config-part-3-standard-form-element-options" class="wp_rp_title">Zend Form Mastery with Zend Config – Part 3 Standard Form &#038; Element Options</a></li><li
data-position="4" data-poid="in-9461" ><a
href="http://www.maltblue.com/php/zend-form-mastery-with-zend-config-part-2-core-form-configuration" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form Mastery with Zend Config &#8211; Part 2 Core Form Configuration" title="" /></a><a
href="http://www.maltblue.com/php/zend-form-mastery-with-zend-config-part-2-core-form-configuration" class="wp_rp_title">Zend Form Mastery with Zend Config &#8211; Part 2 Core Form Configuration</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=01FjN3UulZ8:EqhK-rq-eug:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=01FjN3UulZ8:EqhK-rq-eug:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=01FjN3UulZ8:EqhK-rq-eug:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=01FjN3UulZ8:EqhK-rq-eug:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=01FjN3UulZ8:EqhK-rq-eug:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=01FjN3UulZ8:EqhK-rq-eug:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=01FjN3UulZ8:EqhK-rq-eug:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=01FjN3UulZ8:EqhK-rq-eug:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=01FjN3UulZ8:EqhK-rq-eug:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=01FjN3UulZ8:EqhK-rq-eug:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=01FjN3UulZ8:EqhK-rq-eug:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/01FjN3UulZ8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/zend-framework/simple-zend-framework-2-forms/feed</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://www.maltblue.com/zend-framework/simple-zend-framework-2-forms</feedburner:origLink></item> <item><title>5 Reasons Coding Standards Are Essential</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/NThwIF7SmhM/5-reaons-coding-standards-are-essential</link> <comments>http://www.maltblue.com/software-engineering-2/5-reaons-coding-standards-are-essential#comments</comments> <pubDate>Tue, 12 Mar 2013 08:00:26 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Software Engineering]]></category> <category><![CDATA[development]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[PHP]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12145</guid> <description><![CDATA[Whenever you're developing web applications, are you consistent, do you apply a coding standard? Do you and your team have an agreed upon coding standard? If you don't, you're asking for trouble. Here's Why]]></description> <content:encoded><![CDATA[<p>Whenever you&#8217;re working on a project, are you consistent? Are you consistent in your coding style, consistent in your documenting, consistent in your database naming conventions? Better yet, do you and your team have a coding standard which you consistently adhere to?</p><p>If you don&#8217;t, you&#8217;re buying yourself and others a world of pain &#8211; <strong>which is painlessly simple to avoid</strong>.</p><p>Today I&#8217;m banging the drum, shouting from the street corner, calling from the cathedral spire, imploring you to do one thing, above all else &#8211; pick a coding standard and then <strong>BE CONSISTENT</strong>!</p><p>I don&#8217;t care if you hate standards, I don&#8217;t care if you think all of them are flawed, I don&#8217;t care if you feel locked in, chained up, with all your creativity is stifled.</p><p>Because if you think this way &#8211; <strong>You&#8217;re Wrong</strong>.</p><h2>Poor, Inconsistent Code &#8211; Causes You Pain</h2><p>I used to think this way but saw the, proverbial, light. Why am I banging on so hard today? At Malt Blue, I have the joy of working on a wide range of <a
href="http://www.maltblue.com/contact">freelance web application projects</a>, both big and small.</p><p>However a recent project I took over gave me reason to pause. This project, had a lot going for it. It seemed to have had good intent with the basics of a meaningful design behind it. It had potential to be something really worthwhile. It could have been a maintainable project which wouldn&#8217;t have ended up costing the client quite a lot of money to support.</p><p>Unfortunately, a number of things were done wrong, the key being <strong>inconsistency</strong>. This led to a series of problems in the code, which I&#8217;ll summarize for the sakes of brevity. The are as follows:</p><ul><li>Extremely time consuming to get to grips with the code base</li><li>Code was not intuitive or semantically meaningful</li><li>It was hard to see what linked to what &#8211; and more importantly &#8211; <strong>why</strong></li><li>Time was required to be spent re-reading the same blocks repeatedly for understanding</li><li>Very difficult to tell where to find relevant sections of code</li></ul><p>Here&#8217;s some examples of what was encountered:</p><ul><li>The code base was littered with large swathes of <strong>commented out code</strong></li><li><acronym
title="Structured Query Language">SQL</acronym> queries were written using a DB abstraction layer, then later <strong>composed manually</strong></li><li>Variables and configuration options were named <strong>&#8220;my&#8221;</strong>, <strong>&#8220;m&#8221;</strong>, <strong>&#8220;last&#8221;</strong> and so on</li><li>Multiple functions, with different names, in different modules performed <strong>nearly identical functionality</strong></li><li>Operations were performed in segments of code, multiple layers deep, <strong>with no semantic direction</strong></li></ul><p>To cut a long story short, countless hours were spent, searching, tidying, documenting, trying almost in vain, to understand a code base <strong>needlessly</strong>.</p><p>If the earlier developers would have adhered to a coding standard, not to be confused with a coding style, a lot of this could have been avoided.</p><p>Now I know some people hate coding standards. But if they want to waste time, both theirs and others, I never want to work on their projects.</p><p>So find a standard which works for your business, your organization &#8211; <strong>you</strong> &#8211; and stick to it ardently. I don&#8217;t care which one you adhere to (within reason) &#8211; <strong>so long as you adhere to one</strong>.</p><p>There are a wide range of standards to choose from. Personally I use the <a
href="http://framework.zend.com/manual/1.12/en/coding-standard.html">Zend Framework coding standard</a> as I primarily work on Zend Framework-based projects.</p><p>But if you have another one, such as <a
href="http://pear.php.net/manual/en/standards.php">Pear</a>, <a
href="http://www.gnu.org/prep/standards/">GNU</a>, <a
href="http://symfony.com/doc/2.0/contributing/code/standards.html">Symfony</a>, even <a
href="http://codex.wordpress.org/WordPress_Coding_Standards">WordPress</a>, make sure you know why, or if you&#8217;re in a team, you&#8217;re all in agreement and then make sure you adhere to it.</p><p>Now that I&#8217;ve had a rant, here&#8217;s the benefits they provide:</p><h2>Your Code is Easier to Read</h2><p>When you use a standard, your code is readable, both to you and others. Why, because it&#8217;s consistent. Now, it might not be the best standard, but at least, in a short period of time, you will be able to follow the flow.</p><p>Take the following code for example. To some it may seem trivial. But if you imagine this throughout a code base (even with a formatter in an IDE or script) this code is hard to read. Let&#8217;s leave out the obvious spelling mistakes</p><pre>/**
 * @var array
 */
protected $_messageTemplates = array(self::OBJECT_CATEGORY_NAME_EXISTS_INSERT =&gt; '"%value%" is already chooosen. Pleas select another.',
        self::OBJECT_CATEGORY_NAME_EXISTS_UPDATE =&gt; '"%value%" is already chooosen. Pleas select another.',
);
</pre><h2>Your Code is Easier to Understand</h2><p>This is perhaps the biggest point for me. Whether it&#8217;s the variable naming convention or otherwise, the intent of your code is easier to follow. Take the following example:</p><pre>/**
 * @var array
 */
protected $_messageVariables = array(
        'nice1' =&gt; '_nice1',
        'nice2' =&gt; '_nice2'
);
//...
public function eventContact($value, $niceName, $params = null)
{
    $this-&gt;_nice1 = $params[0];
    $this-&gt;_nice2 = $params[1];
    $this-&gt;_setValue($value);
    if ($this-&gt;_value == '' &amp;&amp; $this-&gt;_nice1 == '' &amp;&amp; $this-&gt;_nice2 == '') {
        $this-&gt;_error(self::MISMATCH);
    }
    return self::$_instance;
}
</pre><p>I&#8217;m not a rocket scientist or a Rhodes scholar, but neither am I unintelligent. But I can&#8217;t infer what <em>nice1 and </em>nice2 are meant to be for.</p><p>Can you? What do you think the class it was in may have been doing? Here&#8217;s a tip, it was for <strong>validating contact information</strong>.</p><h2>Your Code is Easier to Maintain</h2><p>From a model class in the same code base, here&#8217;s another example:</p><pre>final public function query($query)
{
    return $this-&gt;_db-&gt;query($query);
}
final public function select()
{
    return $this-&gt;_db-&gt;select();
}
final public function fetchAll($select)
{
    return $this-&gt;_db-&gt;fetchAll($select);
}
final public function fetchRow($select)
{
    return $this-&gt;_db-&gt;fetchRow($select);
}
final public function fetchPairs($select)
{
    return $this-&gt;_db-&gt;fetchPairs($select);
}
</pre><p>The class constructor initializes a protected member variable, <strong>_db</strong>, with the application database connection, which these functions use. However, they&#8217;re doing nothing more than wrapping internal functionality. Here is another example:</p><pre>final class My_Enums_DateFormat {
    const MYSQL_DATE_TIME           = 'Y-m-d H:i:s';
    const MYSQL_DATE                = 'Y-m-d';
    const ADMIN_NICE                = 'j M Y h:i:s A';
    const DAY_MONTH_YEAR_HOUR_MIN_SEC   = 'd/m/Y H:i:s';
    const MONTH_DAY_YEAR_HOUR_MIN_SEC   = 'm/d/Y H:i:s';
    const MONTH_DAY_YEAR_HOUR_MIN_SEC_MERIDIAN  = 'm/d/Y h:i:s A';
    const DAY_MONTH_YEAR                = 'd/m/Y';
    const MONTH_DAY_YEAR                = 'm/d/Y';
    const HOUR                      = 'H';
    const MINUTE                    = 'i';
    const MERIDIAN                  = 'A';
    const SMALL_HOUR                = 'h';
    const FRONT_END_NICE            = 'F j, Y';
    const MYSQL_TIME                = 'H:i:s';
    const ADMIN_TIME                = 'h:i:s A';
    const TIME                      = 'g:i a';
    const TWENTY_FOUR_HOUR          = 'Hi';
    const DOWNLOAD_DATE             = 'Ymd';
    //...
}
</pre><p>This doesn&#8217;t strictly fall in to the above category &#8211; more in to the DRY. However, what is the purpose of writing code which replicates existing functionality, i.e., <a
href="http://php.net/manual/en/book.datetime.php"><acronym
title="Pre-Hypertext Processing">PHP</acronym> DateTime</a>, <a
href="http://framework.zend.com/manual/1.12/en/zend.date.html">Zend Date</a> et al? Why would you do this?</p><p>Why would you write functionality yourself which already exists, has a range of high quality unit tests, has had <strong>10&#8242;s, 100&#8242;s or 1000&#8242;s</strong> of eyes on on it, verifying its quality, holding it up to scrutiny?</p><p>Please don&#8217;t do this &#8211; unless there&#8217;s a really good reason for it.</p><h2>Your Code is Easier to Collaborate On</h2><p>As a result of all of these points, code is harder to collaborate on. Why? If it&#8217;s hard for one person to work on a code base without wondering where errors might turn up, extrapolate it over a team of 2, 3, 5 or more.</p><p>With clean code and a clear and concise standard which&#8217;s adhered to, at the very least ensures if you&#8217;re going to write rubbish code, it&#8217;s clear rubbish.</p><p>When you don&#8217;t though, as I&#8217;m sure you don&#8217;t you&#8217;re well on your way to building high quality, maintainable code, now and in to the future.</p><h2>What are Your Horror Stories?</h2><p>You&#8217;ve heard mine, now I want to hear your worst experiences. What have you encountered? More importantly, what have you done about it? Was it too hard to overcome or was it manageable?</p><p>Share with us all in the comments <strong>today</strong>. The best (or is that worst) story gets <strong>a free copy of the next edition of <acronym
title="Pre-Hypertext Processing">PHP</acronym> Architect magazine</strong>.</p><p>image copyright <a
href="http://flic.kr/p/dxi7Hk" title="image copyright marsmet481">marsmet481</a></p><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-12189" ><a
href="http://www.maltblue.com/software-engineering-2/how-simplicity-leads-to-greater-productivity-quality-and-satisfaction" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/04/6193875042_55b0507bcc-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="How Simplicity Leads to Greater: Productivity, Quality &amp; Satisfaction" title="" /></a><a
href="http://www.maltblue.com/software-engineering-2/how-simplicity-leads-to-greater-productivity-quality-and-satisfaction" class="wp_rp_title">How Simplicity Leads to Greater: Productivity, Quality &amp; Satisfaction</a></li><li
data-position="1" data-poid="in-370" ><a
href="http://www.maltblue.com/zend-framework/a-big-thank-you-to-mayflower-gmb-h" class="wp_rp_thumbnail"><img
src="http://www.maltblue.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/2.jpg" alt="A big thank you to Mayflower GmbH" /></a><a
href="http://www.maltblue.com/zend-framework/a-big-thank-you-to-mayflower-gmb-h" class="wp_rp_title">A big thank you to Mayflower GmbH</a></li><li
data-position="2" data-poid="in-457" ><a
href="http://www.maltblue.com/php/11-reasons-why-a-php-framework-is-better-than-raw-php" class="wp_rp_thumbnail"><img
src="http://www.maltblue.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/23.jpg" alt="11 Reasons Why a PHP Framework is better than Raw PHP" /></a><a
href="http://www.maltblue.com/php/11-reasons-why-a-php-framework-is-better-than-raw-php" class="wp_rp_title">11 Reasons Why a PHP Framework is better than Raw PHP</a></li><li
data-position="3" data-poid="in-11313" ><a
href="http://www.maltblue.com/opinion/what-is-a-professional-php-freelancer" class="wp_rp_thumbnail"><img
width="150" height="112" src="http://www.maltblue.com/wp-content/uploads/2012/10/4888600941_9c41c2b126.jpeg" class="attachment-thumbnail wp-post-image" alt="What Is a Professional PHP Freelancer?" title="" /></a><a
href="http://www.maltblue.com/opinion/what-is-a-professional-php-freelancer" class="wp_rp_title">What Is a Professional PHP Freelancer?</a></li><li
data-position="4" data-poid="in-450" ><a
href="http://www.maltblue.com/php/11-reasons-why-raw-php-is-better-than-a-framework" class="wp_rp_thumbnail"><img
src="http://www.maltblue.com/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/23.jpg" alt="11 Reasons Why Raw PHP is better than a Framework" /></a><a
href="http://www.maltblue.com/php/11-reasons-why-raw-php-is-better-than-a-framework" class="wp_rp_title">11 Reasons Why Raw PHP is better than a Framework</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=NThwIF7SmhM:yLvtSXl1A5c:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=NThwIF7SmhM:yLvtSXl1A5c:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=NThwIF7SmhM:yLvtSXl1A5c:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=NThwIF7SmhM:yLvtSXl1A5c:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=NThwIF7SmhM:yLvtSXl1A5c:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=NThwIF7SmhM:yLvtSXl1A5c:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=NThwIF7SmhM:yLvtSXl1A5c:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=NThwIF7SmhM:yLvtSXl1A5c:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=NThwIF7SmhM:yLvtSXl1A5c:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=NThwIF7SmhM:yLvtSXl1A5c:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=NThwIF7SmhM:yLvtSXl1A5c:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/NThwIF7SmhM" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/software-engineering-2/5-reaons-coding-standards-are-essential/feed</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://www.maltblue.com/software-engineering-2/5-reaons-coding-standards-are-essential</feedburner:origLink></item> <item><title>Zend Framework 2 ServiceManager – Web Application Development Simplified</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/BVkYd8FzPYo/zend-framework-2-servicemanager</link> <comments>http://www.maltblue.com/tutorial/zend-framework-2-servicemanager#comments</comments> <pubDate>Wed, 30 Jan 2013 04:38:25 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[frameworks]]></category> <category><![CDATA[Zend Framework]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12119</guid> <description><![CDATA[The Zend Framework 2 ServiceManager simplifies the web application development process by making configuration a breeze. In this, the 4th post introducing Zend Framework 2, you will learn what the ServiceManager is how to use it and how it simplifies applicaiton development time.]]></description> <content:encoded><![CDATA[<div
class="author-box"><ul><li><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection" title="Zend Framework 2 Core Concepts – Dependency Injection">Part 1 &#8211; Zend Framework 2 Core Concepts – Dependency Injection</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" title="Zend Framework 2 Modules – The Application’s Heart">Part 2 &#8211; Zend Framework 2 Modules – The Application’s Heart</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" title="Zend Framework 2 Event Manager – A Gentle Introduction">Part 3 &#8211; Zend Framework 2 Event Manager – A Gentle Introduction</a></li></ul></div><h2>Summary</h2><p>The Zend Framework 2 Service Manager simplifies web application development in a number of ways, primarily by making configuration a breeze. In this, the 4th post introducing Zend Framework 2, you will learn what the ServiceManager is, how to use it and how it simplifies app development time.</p><h2>Getting Started</h2><p>Welcome to the Zend Framework 2 Introduction 4-part series finale. Recapping the series so far:</p><ul><li><a
title="Zend Framework 2 Core Concepts - Dependency Injection" href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection">In part one</a>, we went through Dependency Injection (DI)</li><li><a
title="Zend Framework 2 Modules - The Application's Heart" href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart">In part two</a>, we looked at Modules and the ModuleManager</li><li><a
title="Zend Framework 2 EventManager - A Gentle Introduction" href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction">In part three</a>, we looked at the EventManager</li></ul><p>In this, the fourth and final installment, we look at the <strong>ServiceManager</strong> component. This is a highly critical, but potentially misunderstood, aspect of the framework. One that, when understood, makes the rest of the framework a breeze (well, <em>close</em>).</p><p>From reading various blog posts and comments, it&#8217;s often believed that the ServiceManager over-complicates the entire framework. Some people say it&#8217;s an attempt to: <strong>out Java Java</strong>.</p><p><strong>I &#8211; completely &#8211; disagree!</strong></p><p>I believe that it&#8217;s this fundamental concept that <strong>makes the framework simpler</strong>, that makes developing web applications with it easier, less stressful and more maintainable. I hear scoffing, <em>I hear peals of laughter</em>, I hear the embers of a flamewar being stoked <strong>to burn me alive at the stake</strong>.</p><p>To support my point, in this post, I&#8217;m going to do 3 things:</p><ol><li>Give you a good introduction to what the ServiceManager is</li><li>Show you how to configure it</li><li>Step you through a hands-on example of using it</li></ol><p>Stay on to the end as we consider the critical question.</p><h2>What is the ZF2 ServiceManager</h2><p>Put in simplest terms, the ZF ServiceManager component is an implementation of <a
href="http://en.wikipedia.org/wiki/Service_locator_pattern">the Service Locator pattern</a>; in short a simple application registry that provides objects (<em>in a lazy loaded fashion</em>) within application as needed &#8211; but with some nice additions.</p><p>It allows us to perform <a
href="http://en.wikipedia.org/wiki/Inversion_of_control">Inversion of Control (IoC)</a>, which allows us to remove dependencies and tight coupling from our applications. The result of this, <a
title="Zend Framework 2 Core Concepts – Dependency Injection" href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection">when combined with dependency injection</a> and <a
title="Zend Framework 2 Event Manager – A Gentle Introduction" href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction">simple event management</a> is <strong>applications that are simpler to build, test and maintain</strong>.</p><p>You can try to think of it in more complex ways if you&#8217;d like to, but really there&#8217;s no need. Where it does get a little complicated however, at least initially, is how it&#8217;s all configured. I grant you, that does take a bit of getting your head around &#8211; but not too much.</p><h2>How Do You Configure It?</h2><p>The Service Manager is able to be configured <strong>in 7 key ways</strong>. These are:</p><ul><li><strong>abstract factories:</strong> This is one of a fully qualified class name, or an object implementing Zend\ServiceManager\AbstractFactoryInterface. This approach provides flexibility and extensibility to the ServiceManager. If, on request, the ServiceManager isn&#8217;t able to locate a class, it iterates through the registered Abstract Factories to see if any of them are able to satisfy the object request.</li><li><strong>factories:</strong> A fully qualified class name, <acronym
title="Pre-Hypertext Processing">PHP</acronym> callable object, or a class implementing Zend\ServiceManager\FactoryInterface. These handle the dependency injection aspect of the ServiceManager.</li><li><strong>invokables:</strong> A string, which is a fully qualified class name, able to be instantiated later.</li><li><strong>initializers:</strong> A fully qualified class name, <acronym
title="Pre-Hypertext Processing">PHP</acronym> callable object, or a class implementing Zend\ServiceManager\InitializerInterface. If listed, will be applied to objects retrieved from the Service Manager to perform additional initialization.</li><li><strong>configuration classes:</strong> This is a class implementing Zend\ServiceManager\ConfigInterface. Classes implementing this interface are able to configure the Service Manager, performing the initialization that is covered in these seven points.</li><li><strong>aliases:</strong> An associative array of aliases to services (or aliases to aliases). It may not seem like a good idea, but from a readability perspective, I believe this is an excellent technique to have available.</li><li><strong>shared:</strong> Depending on your application or circumstance, you may want to provide single access to an object, or return a new copy on each request. By default, when an object is retrieved from the Service Manager if it&#8217;s the first request, the object is instantiated and returned. If it&#8217;s any after that, the original object is returned.</li></ul><p>What&#8217;s really great about this approach, is that each module loaded or created can also be a service provider. To do so, they need to do one of the following:</p><ol><li>Implement the <strong>Zend\ModuleManager\Feature\ServiceProviderInterface</strong></li><li>Implement <strong>getServiceConfig()</strong></li></ol><p>As <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.service-manager.quick-start.html">the manual indicates</a>, this function needs to return:</p><ol><li>An <strong>array</strong> or <strong>Traversable object</strong></li><li>The name of a class implementing <strong>Zend\ServiceManager\ConfigInterface</strong></li><li>An instance of either <strong>Zend\ServiceManager\Config</strong>, or an object implementing <strong>Zend\ServiceManager\ConfigInterface</strong>.</li></ol><h2>A Simple Code Example</h2><p>I&#8217;ve been creating a Generic module throughout this series and in it, I&#8217;ve added a simple model that lets me retrieve information from a SQLite database. So what better choice to use for an example that that.</p><p>In <strong>module/Generic/Module.php</strong>, I have an implementation of <strong>getServiceConfig</strong> which is as follows (formatted for readability):</p><pre>// Add this method:
public function getServiceConfig()
{
    return array(
        'factories' =&gt; array(
            'Generic\Model\AlbumTable' =&gt;  function($sm) {
                $tableGateway = $sm-&gt;get('AlbumTableGateway');
                $table = new AlbumTable($tableGateway);
                return $table;
            },
            'AlbumTableGateway' =&gt; function ($sm) {
                $dbAdapter = $sm-&gt;get(
                    'Zend\Db\Adapter\Adapter'
                );
                $resultSetPrototype = new ResultSet();
                $resultSetPrototype-&gt;setArrayObjectPrototype(
                    new Album()
                );
                return new TableGateway(
                    'album',
                    $dbAdapter,
                    null,
                    $resultSetPrototype
                );
            },
        )
    );
}</pre><p>You can see here I&#8217;m configuring it with the &#8216;<em>factories</em>&#8216; option. In there I have two options:</p><ul><li><strong>Generic\Model\AlbumTable</strong></li><li><strong>AlbumTableGateway</strong></li></ul><p>Both of these use anonymous functions for the configuration. Now, let&#8217;s pop over to where they&#8217;re used in the <strong>IndexController</strong>. The default action, Index, goes as follows:</p><pre>public function indexAction()
{
    return new ViewModel(array(
        'albums' =&gt; $this-&gt;getAlbumTable()-&gt;fetchAll(),
    ));
}</pre><p>It calls the getAlbumTable method, which is as follows:</p><pre>public function getAlbumTable()
{
    if (!$this-&gt;albumTable) {
        $sm = $this-&gt;getServiceLocator();
        $this-&gt;albumTable = $sm-&gt;get('AlbumTableGateway');
    }
    return $this-&gt;albumTable;
}</pre><p>Now that we have the configuration and usage together, let&#8217;s see how it works. In indexAction, we set a variable &#8216;<strong>albums</strong>&#8216;, which is the result of calling the fetchAll method on the object returned from the <strong>getAlbumTable</strong> method.</p><p>In the getAlbumTable method, we retrieve a copy of the application Service Locator object via the <strong>getServiceLocator</strong> method. We then retrieve the AlbumTableGateway object, by passing the name, as a string, to the get method of the Service Locator object.</p><p>Assuming the object is in the Service Locator registry and suitably configured, it&#8217;s then passed as the return value from the function, allowing us to call the method on it.</p><p>Looking back in to the configuration of the object we see it as follows:</p><pre>'AlbumTableGateway' =&gt; function ($sm) {
    $dbAdapter = $sm-&gt;get(
        'Zend\Db\Adapter\Adapter'
    );
    $resultSetPrototype = new ResultSet();
    $resultSetPrototype-&gt;setArrayObjectPrototype(
        new Album()
    );
    return new TableGateway(
        'album',
        $dbAdapter,
        null,
        $resultSetPrototype
    );
},</pre><p>We see we have a factory configuration, labelled <strong>AlbumTableGateway</strong> configured by an anonymous function.</p><p>You can see we first we use the ServiceManager to get access to the application-wide database adapter (I&#8217;ll cover it in a sec), by retrieving the object configured with the string <strong>Zend\Db\Adapter\Adapter</strong>.</p><p>We then create <a
href="http://framework.zend.com/manual/2.0/en/modules/zend.db.result-set.html">a new ResultSet object</a> and set the prototype to be an Album object. When that&#8217;s done, we then create and return a new TableGateway object, specifying the type, database adapter and result set prototype.</p><p>Now, I&#8217;m deliberately skipping over delving in to the intricacies of the Zend_Db class here &#8211; as it&#8217;s really, a bit outside the purposes of this post. But I encourage you to give it a good read in addition to what you read here.</p><p>Now, for the final part, in config/autoload/global.php I have the following configuration:</p><pre>$dbDSN = 'sqlite:' . dirname(__DIR__) .
    '/../data/databases/zf2skeleton.sq3.sqlite';
return array(
    'db' =&gt; array(
        'driver' =&gt; 'Pdo',
        'dsn'    =&gt; $dbDSN,
        'driver_options' =&gt; array(
            PDO::MYSQL_ATTR_INIT_COMMAND =&gt; 'SET NAMES \'UTF8\''
        ),
    ),
    'service_manager' =&gt; array(
        'factories' =&gt; array(
            'Zend\Db\Adapter\Adapter'
                =&gt; 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
    ),
);</pre><p>You can see how the Database adapter is made available, configured using the same convention &#8211; allowing me to query a <a
href="http://www.sqlite.org/">SQLite version 3 database</a> throughout the application.</p><p>Don&#8217;t forget, all code is available for download from the Malt Blue Github repository. Grab a copy of it and tell me what you think.</p><h2>What We Have Learned?</h2><p>This process of stepping through the configuration and usage of the ServiceManager has shown us X things:</p><ol><li><strong>Configuration Is Simple:</strong> Whilst a bit involved (because of all the locations where configurations can be located) it actually is simple because it follows a clearly defined set of conventions and stored in a standard set of locations.</li><li><strong>It&#8217;s Easy to Debug:</strong> By having standard conventions and locations, we can track configurations in the application logically and systematically.</li><li><strong>It Works with Across Modules:</strong> Whereas in Zend Framework 1, we had to jump through hoops to work with multiple modules, in ZF2 it&#8217;s all baked in. Just follow the conventions and it works.</li><li><strong>Applications Are More Dependable:</strong> This is a bit of a reiteration of the previous points. But by being able to configure applications reliably, simpler, in a readily debuggable manner, you spend less time and effort, effort which can be spent more meaningfully in other aspects of development (and your business).</li><li><strong>Easier to Maintain:</strong> When applications as more consistent, predictable, debuggable, logically (in my mind if nowhere else), they&#8217;re easier to optimise. Why? Because you&#8217;re working with a known quantity. Possibly a little &#8220;boring&#8221; but following convention makes adding new components quicker and more predictable. Being a maintainer, you know how applications hang together, you know where to look, the options which can be used, how to override them and so on.</li></ol><h2>Does it Really Make Development Simpler?</h2><p>This is the burning question in this post. Does it really make web application development simpler? In short, <strong>yes</strong>. Now, at first, there&#8217;s a lot to cover, there&#8217;s a lot to learn. I grant you that.</p><p>There&#8217;s the 7 points mentioned above and you have to work with the different ways in which each work. Fine &#8211; <em>I agree it does require work</em>.</p><p>But think about any skill you&#8217;ve learned. Whether it was riding a bike, learning calligraphy, building running fitness, or what I&#8217;m doing &#8211; learning German.</p><p>At first it requires effort, it requires discipline and it requires concentration. It&#8217;s not easy, sure. But with time, this new skill makes doing what you used to do much simpler, such that you do more in less time, with less effort, with less concentration.</p><p>Consider the amount of work that went in to Zend Framework 1 applications and configuring them &#8211; especially integrating modules and the associated configurations.</p><p><a
href="http://evan.pro/zf2-modules-talk.html#slide1">As Evan Coury well said</a> &#8211; <strong><em>they sucked!</em></strong></p><p>There was the application.ini file, the module configuration that you could choose from a number of good implementations to get it to work, you could roll your own option and more.</p><p>Now, we have the option to spend some time learning, but with the result of ultimately writing cleaner applications, which are simpler to maintain both in terms of time and effort.</p><p>We&#8217;ll have applications which are much more:</p><ul><li>Flexible</li><li>Testable</li><li>Configurable</li><li>Optimizable</li></ul><p>I believe, therefore, it&#8217;s worth the investment of your time to learn. I believe it really is a blessing (potentially in disguise). I&#8217;m a learner, like you. So I want to know what you think, if you disagree with me. If you do, comment and tell me.</p><h2>Get the Code</h2><p>The code for this post &#8211; and all the posts in <a
title="Zend Framework 2 Core Concepts – Dependency Injection" href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection">the Zend Framework 2 introductory series</a> &#8211; is <a
title="Zend Framework 2 - Introductory Application" href="https://github.com/maltblue/ZendFramework2-Introduction">available on the Malt Blue Github account</a>. I encourage you to clone a copy, play with it, comment on it, improve on it.</p><h2>Over to You</h2><p>Do you agree with me or want to flame me right now? If you agree with me that the ServiceManager will simplify use of Zend Framework 2, share with us how in the comments.</p><p>Alternatively, if you agree more with others, that it&#8217;s a pointless, over-complication, of what should be kept simple, say that too.</p><p>We can all grow through shared, constructive, opinions.</p><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-12103" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Event Manager &#8211; A Gentle Introduction" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction" class="wp_rp_title">Zend Framework 2 Event Manager &#8211; A Gentle Introduction</a></li><li
data-position="1" data-poid="in-12061" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/Post-Image-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Modules &#8211; The Application&#8217;s Heart" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_title">Zend Framework 2 Modules &#8211; The Application&#8217;s Heart</a></li><li
data-position="2" data-poid="in-10781" ><a
href="http://www.maltblue.com/php/why-kohana-is-an-excellent-alternative-to-zend-framework" class="wp_rp_thumbnail"><img
width="150" height="48" src="http://www.maltblue.com/wp-content/uploads/2012/07/kohana1.png" class="attachment-thumbnail wp-post-image" alt="Why Kohana is an Excellent Alternative to Zend Framework" title="" /></a><a
href="http://www.maltblue.com/php/why-kohana-is-an-excellent-alternative-to-zend-framework" class="wp_rp_title">Why Kohana is an Excellent Alternative to Zend Framework</a></li><li
data-position="3" data-poid="in-9041" ><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-1-custom-filter-paths" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form Mastery with Zend Config &#8211; Part 1 Custom Filter Paths" title="" /></a><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-1-custom-filter-paths" class="wp_rp_title">Zend Form Mastery with Zend Config &#8211; Part 1 Custom Filter Paths</a></li><li
data-position="4" data-poid="in-11989" ><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Core Concepts &#8211; Dependency Injection" title="" /></a><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection" class="wp_rp_title">Zend Framework 2 Core Concepts &#8211; Dependency Injection</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=BVkYd8FzPYo:Pj2cCMpQoWA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=BVkYd8FzPYo:Pj2cCMpQoWA:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=BVkYd8FzPYo:Pj2cCMpQoWA:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=BVkYd8FzPYo:Pj2cCMpQoWA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=BVkYd8FzPYo:Pj2cCMpQoWA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=BVkYd8FzPYo:Pj2cCMpQoWA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=BVkYd8FzPYo:Pj2cCMpQoWA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=BVkYd8FzPYo:Pj2cCMpQoWA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=BVkYd8FzPYo:Pj2cCMpQoWA:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=BVkYd8FzPYo:Pj2cCMpQoWA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=BVkYd8FzPYo:Pj2cCMpQoWA:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/BVkYd8FzPYo" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/tutorial/zend-framework-2-servicemanager/feed</wfw:commentRss> <slash:comments>9</slash:comments> <feedburner:origLink>http://www.maltblue.com/tutorial/zend-framework-2-servicemanager</feedburner:origLink></item> <item><title>Zend Framework 2 Event Manager – A Gentle Introduction</title><link>http://feedproxy.google.com/~r/MaltBlue/~3/I4VIz53lfcM/zend-framework-2-event-manager-a-gentle-introduction</link> <comments>http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction#comments</comments> <pubDate>Tue, 15 Jan 2013 10:25:07 +0000</pubDate> <dc:creator>Matthew Setter</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[eventmanager]]></category> <category><![CDATA[Zend Framework]]></category> <category><![CDATA[zend framework 2]]></category> <guid isPermaLink="false">http://www.maltblue.com/?p=12103</guid> <description><![CDATA[Today I take you through the Zend Framework 2 EventManager. We'll look at the EventManager key patterns, how it works and step through with some hands on code.]]></description> <content:encoded><![CDATA[<div
class="author-box"><ul><li><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection" title="Zend Framework 2 Core Concepts – Dependency Injection">Part 1 &#8211; Zend Framework 2 Core Concepts – Dependency Injection</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" title="Zend Framework 2 Modules – The Application’s Heart">Part 2 &#8211; Zend Framework 2 Modules – The Application’s Heart</a></li><li><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" title="Zend Framework 2 ServiceManager – Web Application Development Simplified">Part 4 &#8211; Zend Framework 2 ServiceManager – Web Application Development Simplified</a></li></ul></div><p>Enjoying the introduction to Zend Framework 2? I hope so. In part one of the series, <a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection">we looked at Dependency Injection</a>, otherwise know as the <strong>I</strong>nversion <strong>o</strong>f <strong>C</strong>ontrol principle.</p><p>Then, in part two, <a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart">we looked at Modules and the ModuleManager</a>, the next key aspects. In this part, we started to work through what they are and stepped through how to build one from scratch; along with some pointers for taking them further.</p><p>In this, the 3rd of 4 parts, I&#8217;m taking you through the next key aspect of the framework &#8211; <strong>the EventManager</strong>. In today&#8217;s post, I&#8217;ll be doing the following:</p><ol><li>Taking you through the EventManager key patterns</li><li>Looking at how it works</li><li>Stepping through using it with some hands on code</li></ol><p>I know there&#8217;s a lot of theory behind each of these concepts, and the framework as a whole, but by having all of this foundation knowledge, the rest of the concepts become a whole lot simpler. <em>Wouldn&#8217;t you agree?</em></p><p>So let&#8217;s get started with knowing how it works</p><h2>It implements the Observer pattern</h2><p><a
href="http://www.maltblue.com/wp-content/uploads/2013/01/500px-Observer.svg_.png"><img
class="aligncenter size-full wp-image-12108" title="Observer Pattern" src="http://www.maltblue.com/wp-content/uploads/2013/01/500px-Observer.svg_.png" alt="Observer Pattern" width="500" height="207" /></a><br
/> Observer pattern, credit: <a
title="Observer Pattern" href="http://en.wikipedia.org/wiki/Observer_pattern">http://en.wikipedia.org/wiki/Observer_pattern</a></p><p>This is the key pattern to be familiar with when understanding the EventManager. The concept is simply this:</p><blockquote><p>An application has a object, which has a registered list of observers. It performs its actions as normal and notifies the observers when a specific event has occurred. These observers are then able to take action relevant to only themselves.</p></blockquote><p>On the surface of it, this is a rather simple and very effective method of looking at development, I&#8217;m sure you&#8217;ll agree. It also has several advantages. These are:</p><ul><li><strong>No Monster Classes:</strong> This allows us to write code can be written with a single purpose in mind, following the <a
href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a>.</li><li><strong>Easier to extend:</strong> So much code starts out simply, then new requests and desires appear. With the Observer pattern, it&#8217;s simple to meet both aims.</li><li><strong>Easier to test:</strong> Imagine trying to test a monolithic codebase, or one which has so many different needs and desires? When each part is simple, concise and decoupled, makes the job of testing far simpler.</li></ul><h2>It implements Aspect-Oriented programming (AOP)</h2><p>This is one area I&#8217;m not yet totally familiar with. But it makes for really interesting reading. <a
href="http://en.wikipedia.org/wiki/Aspect-oriented_software_development">Wikipedia says this about Aspect-Oriented programming</a>:</p><blockquote><p>The motivation for aspect-oriented programming approaches stem from the problems caused by code scattering and tangling. The purpose of Aspect-Oriented Software Development is to provide systematic means to modularize crosscutting concerns.</p><p>The implementation of a concern is scattered if its code is spread out over multiple modules. The concern affects the implementation of multiple modules. Its implementation is not modular.</p><p>The implementation of a concern is tangled if its code is intermixed with code that implements other concerns. The module in which tangling occurs is not cohesive.</p></blockquote><p>In short, I believe you can sum it up thinking about it this way: <strong>Write clean code, well organised code, with one purpose in mind. Code which doesn&#8217;t try to solve on more than one problem.</strong></p><p>For example, if you write code which searches a datasource for information matching a query, it doesn&#8217;t attempt to render the information for the user as well.</p><p><a
href="http://phpmaster.com/explore-aspect-oriented-programming-with-codeigniter-1/">Read this Aspect-Oriented programming series</a> on PHPMaster for a fuller understanding.</p><h2>It has an Event-Driven architecture</h2><p>The following two statements from <a
href="http://en.wikipedia.org/wiki/Event-driven_architecture">an article on Event-driven architecture</a> show why it&#8217;s an excellent approach to take:</p><blockquote><p>Building applications and systems around an event-driven architecture allows these applications and systems to be constructed in a manner that facilitates more responsiveness, because event-driven systems are, by design, more normalized to unpredictable and asynchronous environments.[2]</p><p>Event-driven architecture can complement service-oriented architecture (SOA) because services can be activated by triggers fired on incoming events.[2][3] This paradigm is particularly useful whenever the sink does not provide any self-contained executive.</p></blockquote><p>To help you out a bit more, here&#8217;s an excellent, yet simple, diagram</p><p><a
href="http://www.maltblue.com/wp-content/uploads/2013/01/eda-architecture-ibm.gif"><img
class="aligncenter size-full wp-image-12107" title="EDA Architecture" src="http://www.maltblue.com/wp-content/uploads/2013/01/eda-architecture-ibm.gif" alt="EDA Architecture" width="397" height="188" /></a></p><p><a
href="https://www.ibm.com/developerworks/library/ws-soa-eda-esb/#N100A3">courtesy of IBM</a></p><p>You can see from this definition how Event-Driven architecture, Aspect-Oriented design serve to compliment each other. And by implementing them, Zend Framework 2 allows you to write complex applications in a cohesive, yet greatly decoupled manner.</p><h2>No?</h2><p>Because you can write a series of components (or sub-components) all focusing on doing one, clear, task really well. These components are then linked together through listeners and are triggered (or called in to action) as needed. Not before, not after. I&#8217;d suggest this, in combination with good lazy loading makes it even simpler and more effective. Now, Matthew Weier O&#8217;Phinney may correct me here, but it seems right to me. Do you agree?</p><h3>So what exactly is the EventManager?</h3><p>The Event Manager is the component of the framework <strong>which allows you to hook in to named events in your application</strong>. Not so tough, right?</p><p>I&#8217;m not trying to over-complicate it (despite the lengthy introduction). In essence, it&#8217;s a pretty simple concept, nothing more nothing less. One thing I&#8217;ve been finding, as I learn Zend Framework 2, is there are a variety of ways in which you can use it can get, seemingly, complex.</p><p>Have a look at <a
href="http://zend-framework-community.634137.n4.nabble.com/ZF2-Doing-something-before-calling-the-controller-action-td4656922.html">this zend framework community thread</a> and some of the comments on <a
href="ZF2's%20New%20Controller::init(">MWOP&#8217;s post on ZF2&#8242;s New Controller::init()</a>) to get an idea of current opinion.</p><p>There are an existing set of named events in the framework, such as the dispatch event in controllers. You can also create your own as suits your application&#8217;s purpose. <strong>That&#8217;s step one</strong>.</p><p>Then, you attach (<em>or listen</em>) to those events. When they fire &#8211; <strong>or are triggered</strong> &#8211; your code interrogates the context of the event and responds if needed.</p><p>Not bad hey? Still with me?</p><p>Now, so you have the whole picture, you can also do the following:</p><ul><li><strong>Attach to many events at once:</strong> Need to listen on multiple events, such as logging the occurrence of all actions in a controller being fired? Easy.</li><li><strong>Detach listeners:</strong> Maybe a listener is no longer required, or not available due to a service outage. Then remove it from the list.</li><li><strong>Short-circuit execution:</strong> This helps you stop other listeners executing if, for example, there&#8217;s no further work to be done. It&#8217;s also handy for performance by flattening out the call stack.</li><li><strong>Set priorities on events:</strong> This is handy if different listeners need to fire off earlier or later in the event process. A trivial example is form validation where you want to log information before and afterwards. The higher the number, the higher it&#8217;s priority &#8211; <strong>and the earlier it will fire</strong>.</li></ul><p>I hope you are starting to get an understanding of just how flexible this feature is. You can create simple, reusable, modular code and interlink throughout your application.</p><h2>Let&#8217;s code an EventManager example</h2><p>As I said there are so many possibilities &#8211; and as I&#8217;m still learning myself &#8211; I can&#8217;t do all of them justice. Tell me what you&#8217;ve done in the comments though. So what I&#8217;m going to do is to work through a few examples.</p><p>The first one is one MWOP provided in a recent post. I was looking for a way of testing the event manager and performing simple logging whenever a controller&#8217;s action fired.</p><p>In the code below, we setup the EventManager for our controller, passing in an $events object. It&#8217;s a nice starter example as it&#8217;s so self-contained. We&#8217;re self-attaching if you will.</p><p>Ok, so after we&#8217;ve composed an EventManager instance, we then attach to the <em>dispatch event</em> of the current controller.</p><p>Next we extract the method used for the current request (<em>GET</em>, <em>POST</em> etc). Then, we ask if the method was outside of <em>PUT</em>, <em>DELETE</em> or <em>PATCH</em> or if we had no id query parameter.</p><p>If either of these conditions are met, we do nothing. If either were, we are then redirected to a named route.</p><pre>public function setEventManager(EventManagerInterface $events)
{
    parent::setEventManager($events);
    $controller = $this;
    $events-&gt;attach('dispatch', function ($e) use ($controller) {
        $request = $e-&gt;getRequest();
        $method = $request-&gt;getMethod();
        if (!in_array($method, array('PUT', 'DELETE', 'PATCH'))) {
          // nothing to do return;
        }
        if ($controller-&gt;params()-&gt;fromRoute('id', false)) {
          // nothing to do return;
        }
        // Missing identifier! Redirect. return
        $controller-&gt;redirect()-&gt;toRoute("generic");
    }, 100);
    // execute before executing action logic
 }</pre><h2>Let&#8217;s code another example</h2><p>In this example, what I was trying to do was to get my own head around the process. I was working through basic ZF2 elements, such as <em>forms</em>, <em>controllers</em>, <em>actions</em> etc.</p><p>I&#8217;d already created a simple form, following along with the documentation on the ZendSkeleton application. The example I thought of was logging information about the form details both before and after the validation process.</p><p>So what I&#8217;m doing in the following example is to override and attach a listener to the isValid method. So here&#8217;s the relevant Form class code:</p><pre>&lt;?php
namespace Generic\Form;
use Zend\Form\Form;
use Zend\EventManager\EventManager;
use Zend\EventManager\Event;
use MaltBlue\Listener\Logging;
class AlbumForm extends Form {
  protected $events = null;
  protected $logger = null;
  public function events() {
    if ($this-&gt;events === null) {
      $this-&gt;events = new EventManager(__CLASS__);
      $logListener = new Logging();
      $this-&gt;events()-&gt;attach(
        'isValid.pre',
        array($logListener, 'logOutput')
      );
      $this-&gt;events()-&gt;attach(
        'isValid.post',
         array($logListener, 'logOutput')
      );
    }
    return $this-&gt;events;
  }
  public function isValid() {
    $response = $this-&gt;events()-&gt;trigger(
      __FUNCTION__ . '.pre', $this, $this-&gt;data
    );
    $isValid = parent::isValid();
    $response = $this-&gt;events()-&gt;trigger(
      __FUNCTION__ . '.post', $this, $this-&gt;data
    );
    return $isValid;
  }
  …
}</pre><p>I&#8217;ve created an $events object and defined an events method. In the events method, I instantiate an EventManager object using the current class. I also instantiate a new Logging class, which is, to be fair, a poorly named class which logs to a file, the information available.</p><p>I attach then attach to the self-named isValid.pre and isValid.post, passing the logging class. I then override the isValid method, triggering the pre method before validation and post afterwards, passing in the form class and form data.</p><p>I don&#8217;t hold up execution or change it in anyway as you can see with return $isValid.</p><h2>Now the listener class</h2><pre>&lt;?php
namespace MaltBlue\Listener;
use Zend\Log\Writer\Stream;
use Zend\Log\Logger;
use MaltBlue\Listener\Exception;
class Logging {
  public static function logOutput($event)
  {
    $logdir = dirname(__DIR__) . "/../../data/logs/";
    $stream = @fopen($logdir . "logs.log", 'a', false);
    if (!$stream) {
      throw new Exception\InvalidFileException( 'Failed to open stream' );
    }
    $writer = new Stream($stream);
    $logger = new Logger();
    $logger-&gt;addWriter($writer);
    switch ($event-&gt;getName()) {
      case ("isValid.post"):
        list($id, $title, $artist, $submit) = each( $event-&gt;getParams() );
        $message = sprintf(
          "Post form validation: %s %s ", $title, $artist, $event-&gt;getParam('id')
        );
        $logger-&gt;info($message);
      break;
      case ("isValid.pre"):
        list($id, $title, $artist, $submit) = each( $event-&gt;getParams() );
        $message = sprintf(
          "Pre form validation: %s %s ", $title, $artist, $event-&gt;getParam('id')
        );
        $logger-&gt;info($message);
      break;
    }
  }
}</pre><p>The function, logOutput, above receives an EventManager object and initialises a Zend Log object adding a stream writer. I then have a simple switch statement looking at the $event object.</p><p>It uses one of the methods of the object, getName, to determine what event just fired. If it&#8217;s either isValid.post or isValid.pre, then it takes action, extracting the information passed in through the getParams method. It trivially logs some of the information to a log entry.</p><p>In this, slightly longer example, you can see more of the functionality available. You can see how:</p><ul><li>We can trigger events as required</li><li>Create our own named events suiting our purpose</li><li>Know what event was fired</li><li>Look at the information in the event</li></ul><p>All without extending a class needlessly and poorly. I could have taken a lot of different types of action here. I could have:</p><ul><li>Sent a tweet</li><li>Sent an email</li><li>Displayed further information</li></ul><p>However, I&#8217;ve kept it intentionally simple as my intent is to introduce the EventManager, not give it an exhaustive run through.</p><p>I&#8217;ve provided a list of helpful and valuable links in the further reading section below to help you see how you can use it in a range of forms.</p><h2>What are your thoughts on the Zend Framework EventManager?</h2><p>What I&#8217;ve written here is my take on how the EventManager works and understanding of the key concepts which compose it. However I&#8217;m still learning about it too and would love to hear your understanding about it.</p><p>Do you believe it&#8217;s written the write way and really does allow us to develop cleaner, more effective and scalable applications? Feel free to share your experience and knowledge in the comments below so we can all better use the EventManager in ZF2.</p><h2>Further Reading</h2><ul><li><a
href="http://msdn.microsoft.com/en-us/library/dd129913.aspx">http://msdn.microsoft.com/en-us/library/dd129913.aspx</a></li><li><a
href="http://www.mwop.net/blog/2012-07-30-the-new-init.html">http://www.mwop.net/blog/2012-07-30-the-new-init.html</a></li><li><a
href="http://p0l0.binware.org/index.php/2012/02/18/zend-framework-2-authentication-acl-using-eventmanager/">http://p0l0.binware.org/index.php/2012/02/18/zend-framework-2-authentication-acl-using-eventmanager/</a></li><li><a
href="http://samsonasik.wordpress.com/2012/08/23/zend-framework-2-controllerpluginmanager-append-controller-pluginto-all-controller/">http://samsonasik.wordpress.com/2012/08/23/zend-framework-2-controllerpluginmanager-append-controller-pluginto-all-controller/</a></li><li><a
href="http://zend-framework-community.634137.n4.nabble.com/ZF2-Doing-something-before-calling-the-controller-action-td4656922.html">http://zend-framework-community.634137.n4.nabble.com/ZF2-Doing-something-before-calling-the-controller-action-td4656922.html</a></li></ul><h3 class="related_post_title">Related Posts</h3><ul
class="related_post wp_rp wp_rp_vertical" style="visibility: visible"><li
data-position="0" data-poid="in-12061" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/Post-Image-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Modules &#8211; The Application&#8217;s Heart" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-modules-the-applications-heart" class="wp_rp_title">Zend Framework 2 Modules &#8211; The Application&#8217;s Heart</a></li><li
data-position="1" data-poid="in-11989" ><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 Core Concepts &#8211; Dependency Injection" title="" /></a><a
href="http://www.maltblue.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection" class="wp_rp_title">Zend Framework 2 Core Concepts &#8211; Dependency Injection</a></li><li
data-position="2" data-poid="in-12119" ><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2013/01/zf2-eventmanager-feature-image-resized-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 ServiceManager &#8211; Web Application Development Simplified" title="" /></a><a
href="http://www.maltblue.com/tutorial/zend-framework-2-servicemanager" class="wp_rp_title">Zend Framework 2 ServiceManager &#8211; Web Application Development Simplified</a></li><li
data-position="3" data-poid="in-12234" ><a
href="http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern" class="wp_rp_thumbnail"><img
width="150" height="88" src="http://www.maltblue.com/wp-content/uploads/2012/12/ZF2-Logo.png" class="attachment-thumbnail wp-post-image" alt="Zend Framework 2 &#8211; Hydrators, Models and the TableGateway Pattern" title="" /></a><a
href="http://www.maltblue.com/tutorial/zendframework2-hydrators-models-tablegateway-pattern" class="wp_rp_title">Zend Framework 2 &#8211; Hydrators, Models and the TableGateway Pattern</a></li><li
data-position="4" data-poid="in-9041" ><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-1-custom-filter-paths" class="wp_rp_thumbnail"><img
width="150" height="150" src="http://www.maltblue.com/wp-content/uploads/2010/11/zend-framework-logo-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="Zend Form Mastery with Zend Config &#8211; Part 1 Custom Filter Paths" title="" /></a><a
href="http://www.maltblue.com/zend-framework/zend-form-mastery-with-zend-config-part-1-custom-filter-paths" class="wp_rp_title">Zend Form Mastery with Zend Config &#8211; Part 1 Custom Filter Paths</a></li></ul> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/MaltBlue?a=I4VIz53lfcM:nqx6IG2Lr4A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=I4VIz53lfcM:nqx6IG2Lr4A:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=I4VIz53lfcM:nqx6IG2Lr4A:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=I4VIz53lfcM:nqx6IG2Lr4A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=I4VIz53lfcM:nqx6IG2Lr4A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=I4VIz53lfcM:nqx6IG2Lr4A:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=I4VIz53lfcM:nqx6IG2Lr4A:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=I4VIz53lfcM:nqx6IG2Lr4A:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=I4VIz53lfcM:nqx6IG2Lr4A:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/MaltBlue?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/MaltBlue?a=I4VIz53lfcM:nqx6IG2Lr4A:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/MaltBlue?i=I4VIz53lfcM:nqx6IG2Lr4A:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/MaltBlue/~4/I4VIz53lfcM" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction/feed</wfw:commentRss> <slash:comments>11</slash:comments> <feedburner:origLink>http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction</feedburner:origLink></item> <media:rating>nonadult</media:rating></channel> </rss><!-- Dynamic page generated in 3.516 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-06-17 20:01:09 --><!-- Compression = gzip -->
