<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Evilprofessor.co.uk &#187; ini</title>
	<atom:link href="http://www.evilprofessor.co.uk/tag/ini/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.evilprofessor.co.uk</link>
	<description>The website of Steven Lloyd Watkin</description>
	<lastBuildDate>Thu, 04 Aug 2011 09:56:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Quick Start Symfony DI (Dependency Injection) Tutorial</title>
		<link>http://www.evilprofessor.co.uk/264-quick-start-symfony-di-dependency-injection-tutorial/</link>
		<comments>http://www.evilprofessor.co.uk/264-quick-start-symfony-di-dependency-injection-tutorial/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 14:21:35 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Dependency Injection Container]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_Cache]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[dependency injection]]></category>
		<category><![CDATA[di]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[ini]]></category>
		<category><![CDATA[inversion of control]]></category>
		<category><![CDATA[IOC]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[yaml]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=264</guid>
		<description><![CDATA[What is Dependency Injection (DI)? Dependency injection is a technique that allows for loosely coupled objects within a software application. Generally if an object requires access to the functionality of another it would be instantiated internally leading to tightly coupled systems. By implementing dependency injection we inject the required objects ready for use (sometimes also [...]]]></description>
			<content:encoded><![CDATA[<h2>What is <a href="http://en.wikipedia.org/wiki/Dependency_injection" class="kblinker" target="_blank" title="More about Dependency Injection &raquo;">Dependency Injection</a> (DI)?</h2>
<p>Dependency injection is a technique that allows for loosely coupled objects within a software application. Generally if an object requires access to the functionality of another it would be instantiated internally leading to tightly coupled systems. By implementing dependency injection we inject the required objects ready for use (sometimes also referred to inversion of control &#8211; IOC). Take the following example:</p>
<pre class="php" type="code" name="code">&lt;?php
class DecisionMaker {
    public function makeDecision(array $parameters) {
        // Need the database adapter
        $dp = new DecisionParameters();
        $parameterScore = $dp-&gt;getScore($parameters);
        /* ... Some more decision logic ... */
        return ($parameterScore &gt; 50);
    }
}</pre>
<p>This piece of code is said to be tightly coupled to the <em>DecisionParameters</em> object. Rewriting the above in a loosely coupled fashion we&#8217;d have something like&#8230;.</p>
<pre class="php" type="code" name="code">&lt;?php
class DecisionMaker {
    private $_dp;
    public function __construct($dp) {
        $this-&gt;_dp = $dp;
    }
    public function makeDecision(array $parameters) {
        $parameterScore = $this-&gt;_dp-&gt;getScore($parameters);
        /* ... Some more decision logic ... */
        return ($parameterScore &gt; 50);
    }
}</pre>
<p>Whilst gaining the benefits of loosely coupled code we are adding complexity such that each time an object is instantiated we also have to instantiate its dependencies and pass these in too. For example, this:</p>
<pre class="php" type="code" name="code">$choice = new DecisionMaker();
echo $choice-&gt;makeDecision(array('effort' =&gt; 'low', 'return' =&gt; 'high'));</pre>
<p>now becomes:</p>
<pre class="php" type="code" name="code">$dp = new DecisionParameters();
$choice = new DecisionMaker($dp);
echo $choice-&gt;makeDecision(array('effort' =&gt; 'low', 'return' =&gt; 'high'));</pre>
<p>This situation becomes more painful as the number of dependencies for a class is increased, and what if the dependencies themselves have dependencies? This can quite quickly become an object administration nightmare! Enter dependency injection containers (or frameworks)&#8230;<br />
<span id="more-264"></span></p>
<h2>Dependency Injection Containers/Frameworks</h2>
<p>Dependency injection containers (or frameworks) handle the process of object creation; instantiating and injecting any dependencies before returning an instance to the caller.</p>
<p>In your code rather than create new objects directly we request a copy of the object from the DI container. The object we are returned already has  all its dependencies injected and the object is ready to go.</p>
<h3><a href="http://www.symfony-project.org/" class="kblinker" target="_blank" title="More about Symfony &raquo;">Symfony</a> Dependency Injection Container</h3>
<p>Symfony is probably best known for their full stack <a href="http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller" class="kblinker" target="_blank" title="More about MVC &raquo;">MVC</a> framework however they have also released a number of the components that can be used independently. For example, the dependency injection container we&#8217;re going to talk about here, a <a href="http://www.yaml.org/" class="kblinker" target="_blank" title="More about yaml &raquo;">YAML</a> parser, a templating engine, see <a href="http://components.symfony-project.org/" class="kblinker" target="_blank" title="More about symfony components &raquo;">Symfony components</a> for more.</p>
<p>The Symfony DI container is based on that from the <a href="http://en.wikipedia.org/wiki/Spring_Framework" class="kblinker" target="_blank" title="More about spring framework &raquo;">Spring Framework</a> in <a href="http://www.java.com/en/" class="kblinker" target="_blank" title="More about java &raquo;">Java</a>.</p>
<h2>Bootstrapping</h2>
<p>In order to bootstrap the Symfony dependency injection framework we use code as included below. I have chosen to use YAML just because its easy to read and setup. For maximum speed you may want to write out your containers to plain <a href="http://www.php.net" class="kblinker" target="_blank" title="More about PHP &raquo;">PHP</a> (the Symfony container can do this for you once setup), or alternatively cache the whole container using <a href="http://framework.zend.com/manual/en/zend.cache.html" class="kblinker" target="_blank" title="More about Zend_Cache &raquo;">Zend_Cache</a>, or similar.</p>
<p>To install Symfony DI follow the instructions included here <a href="http://components.symfony-project.org/dependency-injection/installation">http://components.symfony-project.org/dependency-injection/installation</a>, and add it to your path.</p>
<pre class="php" type="code" name="code">// Load the Symfony DI container
require 'sfServiceContainerBuilder.php';
$container = new sfServiceContainerBuilder();
$loader = new sfServiceContainerLoaderFileYaml($container);
$loader-&gt;load(APPLICATION_PATH . '/config/di/services.yml');</pre>
<p>Firstly we instantiate a new container, and then we load our configuration from a YAML file. Note: the DI container can load config from several formats such as <a href="http://en.wikipedia.org/wiki/XML" class="kblinker" target="_blank" title="More about XML &raquo;">XML</a>, YAML, PHP, and INI*.  I tend to include a single YAML file and import other files from within there.</p>
<p>Several configuration files can be imported using different formats, the newer definitions overwriting those that have already been defined. Configuration files can include references to objects and parameters.</p>
<p><em>*INI is only able to define parameters and is unable to import other files</em></p>
<h2>Configuration Example</h2>
<pre>imports:
  - { resource: daos.yml }

parameters:
  username: false

services:
  # Customer model
  model.customer:
    class:  Pro_Customer
    calls:
      - [ setLogger, [ @utils.logger ] ]
      - [ setDao, [ @data.userdata.mysql ] ]
      - [ setUserName, [ %username% ] ]

  # Product model
  model.product:
    class:  Pro_Product
    arguments: [%username%, { type: %accesslevel%, lastlogin: %lastlogin% } ]
    calls:
     - [ setDao, [ @data.product.mysql ] ]

  # Logger
  utils.logger:
    class: Pro_Logger
    constructor: getInstance
    calls:
      - [ setHandle, [ @utils.filewriter ] ]</pre>
<p>I think the code above is fairly self explanatory but for clarity I&#8217;ll explain each part now.</p>
<p>First off we define some imports (i.e. other files to parse), I like to group my configurations for example DAOs in one file, utilities in another and name the file appropriately. Whilst a little slower it speeds up the maintenance of the configuration files. Its also possible to parse files of other formats using different import flags. Files are parsed in order with newer definitions overwriting or amending previously defined services/parameters.</p>
<p>Next we define a parameter, a parameter can generally be any PHP variable type. At this point I didn&#8217;t  know what my username parameter should be (I need to authenticate for that!), so I&#8217;ve defined a default value and I&#8217;ll overwrite that value later. Note, classes aren&#8217;t instantiated until you ask for them so defining parameters a little later is perfectly fine. Following this I define some services:</p>
<ol>
<li>Instantiate Pro_Customer, pass an instance of my logger to the setLogger() method, add in my <a href="http://www.mysql.com/?bydis_dis_index=1" class="kblinker" target="_blank" title="More about mysql &raquo;">MySQL</a> <a href="http://en.wikipedia.org/wiki/Data_access_object" class="kblinker" target="_blank" title="More about data access object &raquo;">data access object</a> (DAO), and pass in the username as well. Each time I ask for this object I want a new instance</li>
<li>Create an instance of Pro_Product, pass arguments of username and an options array to the constructor. After instantiation call setDao() and pass it my product DAO</li>
<li>Give me a copy of Pro_Logger, instantiate it using the getInstance() method and pass a copy of my file writer object via setHandle() once its loaded. My file writer is defined in one of my imports.</li>
</ol>
<p>Within the configuration files <em>services</em> are referenced by prepending the name with an &#8216;@&#8217; symbol, <em>parameters</em> are referenced by prepending and appending with &#8216;%&#8217; symbols, e.g. <em>@utils.logger %username%</em>.</p>
<h2>Adding data post loading</h2>
<p>Sometimes you don&#8217;t know what the value of parameters should be until after you have bootstrapped, as with our <em>username</em> parameter above. In order to overwrite the value the <em>offsetSet()</em> method is used, firstly passing the parameter name followed by its new value:</p>
<pre class="php" type="code" name="code">$container-&gt;offsetSet('username', $username);</pre>
<h2>Getting Objects from the container</h2>
<p>Once setup rather than instantiating objects directly we now go to the DI container to get instances. With the Symfony DI we call the <em>getService() </em>method, passing in a string which describes the variable you wish to retrieve, e.g.</p>
<pre class="php" type="code" name="code">$logger = $container-&gt;getService('utils.logger');</pre>
<p>This will perform the equivalent of:</p>
<pre class="php" type="code" name="code">$logger = Pro_Logger::getInstance();
$fileWriter = new Pro_Writer_FileWriter();
$logger-&gt;setHandler($fileWriter);</pre>
<p>It is possible to determine if the container has an instance of a service by calling the <em>hasService()</em> method, which returns a boolean value.</p>
<p>Its not necessary to have access to the container beyond the top level of your application since once retrieving an instance all of the required dependencies right down to the deepest depths of your application are already setup and waiting to be called.</p>
<h2>Unit Testing</h2>
<p>Dependency injection also has the added benefit of allowing objects to be tested in isolation. Taking the <em>DecisionMaker</em> class example before implementing the dependency injection setup our test results were also dependent on the implementation of the <em>DecisionParameters</em> class.</p>
<p>Should the <em>DecisionParameters</em> class return different results our tests could start failing through no fault of our own. Using dependency injection we can now pass in a <em>DecisionParameters</em> object which returns a known/fixed set of results for certain input parameters, we are now testing <em>DecisionMaker</em> in isolation from any external factors, i.e. if our tests start failing this can be directly attributed to something changing in the <em>DecisionMakeer</em> class. This is particularly important should you be relying on test data from a database for testing.</p>
<h2>Application Configuration</h2>
<p>The way in which your application behaves on your production server will inevitably differ from your development setup. For example, in a development environment the level of logging would be much more granular than on your production system. By altering your dependency injection container configuration files slightly (or parsing an additional configuration file) the altering of behaviour depending on the environment is made simple.</p>
<p>By type hinting on interfaces rather than implementations when setting your dependencies its also possible to swap out components for compatible components with a few lines of YAML or XML. For instance, you may currently access your database via a MySQL DAO (Data Access Object), but in time you may develop a PDO, Zend_Db, or <a href="http://www.doctrine-project.org/" class="kblinker" target="_blank" title="More about Doctrine &raquo;">Doctrine</a> implementation of this DAO. By adding the new implementation into your configuration file suddenly all the objects that used the old MySQL implementation are now using your new implementation without needing to attack the bowels of your application.</p>
<h2>Notes</h2>
<ul>
<li>By setting <em>shared: true</em> in the configuration we are always given the same instance of an object. This is very useful when dealing with objects which contain resources such as database connections, file handles, etc</li>
<li>There are two methods by which dependencies can be injected. One is to pass dependencies with the constructor, or alternatively via setter methods. The generally accepted pattern is to pass required dependencies via the constructor and optionals via setters. My personal preference is to use setters for everything, but this is down to the individual developer</li>
</ul>
<h2>Finally&#8230;.</h2>
<p>Along with a brief discussion on dependency injection and its advantages and disadvantages this has also been a quick-start guide to implementing the Symfony Dependency Injection Container&#8230; hopefully you&#8217;ve seen that it&#8217;s surprisingly quick and easy. From here you&#8217;ll be able to start using dependency injection through your application and look to using many more of the advanced features (although the simple example covers the vast majority of functionality you&#8217;ll require). As always I point you to the <a title="Symfony DI container manual" href="http://components.symfony-project.org/dependency-injection/documentation" target="_blank">manual</a> for further information.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F264-quick-start-symfony-di-dependency-injection-tutorial%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/264-quick-start-symfony-di-dependency-injection-tutorial/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Route requests for sitemap.xml to custom controller/action</title>
		<link>http://www.evilprofessor.co.uk/231-route-requests-for-sitemap-xml-to-custom-controlleraction/</link>
		<comments>http://www.evilprofessor.co.uk/231-route-requests-for-sitemap-xml-to-custom-controlleraction/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 00:13:56 +0000</pubDate>
		<dc:creator>Steven Lloyd Watkin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[ini]]></category>
		<category><![CDATA[Router]]></category>
		<category><![CDATA[Routes]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[Zend_Navigation]]></category>
		<category><![CDATA[Zend_Router]]></category>

		<guid isPermaLink="false">http://www.evilprofessor.co.uk/?p=231</guid>
		<description><![CDATA[In order to direct requests for /sitemap.xml to a custom controller and action in your Zend Framework application simply add the following in your application.ini or alternative config file (e.g. I use navigation.ini): resources.router.routes.sitemap.route = "sitemap.xml" resources.router.routes.sitemap.defaults.controller = index resources.router.routes.sitemap.defaults.action = sitemap Example code for outputting can be seen by creating an action in the [...]]]></description>
			<content:encoded><![CDATA[<p>In order to direct requests for /<a href="http://en.wikipedia.org/wiki/Sitemaps">sitemap.xml</a> to a custom controller and action in your <a href="http://framework.zend.com" class="kblinker" target="_blank" title="More about Zend Framework &raquo;">Zend Framework</a> application simply add the following in your application.ini or alternative config file (e.g. I use navigation.ini):</p>
<pre name="code" class="ini">
resources.router.routes.sitemap.route                = "sitemap.xml"
resources.router.routes.sitemap.defaults.controller  = index
resources.router.routes.sitemap.defaults.action      = sitemap
</pre>
<p>Example code for outputting can be seen by creating an action in the appropriate controller (e.g. my sitemap lies in the index controller, sitemap action):</p>
<pre name="code" class="php">
&lt;<a href="http://www.php.net" class="kblinker" target="_blank" title="More about PHP &raquo;">php</a>
class IndexController
    extends Zend_Controller_Action
{
    /**
     * Renders a sitemap based on Zend_Navigation setup
     */
    public function sitemapAction()
    {
    	echo $this->view->navigation()->sitemap();
    	$this->view->layout()->disableLayout();
    	$this->_helper->viewRenderer->setNoRender(true);
    }
}
</pre>
<p>Sitemaps can quickly and easily be generated using <a href="http://framework.zend.com/manual/en/zend.navigation.html">Zend_Navigation</a>, a great quick tutorial (and generally very useful for Zend Framework tutorials) is <a href="http://www.zendcasts.com/">Zend Casts</a> &#8211; <a href="http://www.zendcasts.com/zend_navigation-dynamically-creating-a-menu-a-sitemap-and-breadcrumbs/2009/06/">Dynamically creating a menu a sitemap and breadcrumbs</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.evilprofessor.co.uk%2F231-route-requests-for-sitemap-xml-to-custom-controlleraction%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://www.evilprofessor.co.uk/231-route-requests-for-sitemap-xml-to-custom-controlleraction/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
