<?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>The Developer Day</title>
	<atom:link href="http://www.thedeveloperday.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thedeveloperday.com</link>
	<description>Staying Curious</description>
	<lastBuildDate>Wed, 10 Mar 2010 01:32:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Zend Framework Advanced Error Controller</title>
		<link>http://www.thedeveloperday.com/custom-profiler-for-live-environments/</link>
		<comments>http://www.thedeveloperday.com/custom-profiler-for-live-environments/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 01:31:58 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[testability]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/custom-profiler-for-live-environments/</guid>
		<description><![CDATA[The default Zend Framework Error Controller generated by Zend_Tool is quite simple. It displays a simple error message, sets a response status and if exception display is enabled in the current environment, an exception message, stack trace and request variables are displayed.
While such a standard error controller may work well for many web applications it [...]]]></description>
			<content:encoded><![CDATA[<p>The default <a href="http://framework.zend.com/">Zend Framework</a> Error Controller generated by <a href="http://framework.zend.com/manual/en/zend.tool.framework.html">Zend_Tool</a> is quite simple. It displays a simple error message, sets a response status and if exception display is enabled in the current environment, an exception message, stack trace and request variables are displayed.</p>
<p>While such a standard error controller may work well for many web applications it may not be suitable for everyone. The main disadvantage of the default <strong>error controller</strong> is that it does not notify developers of the errors that occurred and instead silently logs them. Many enterprise web applications will find this unacceptable and will try to implement their means of solving the issue. In this post I&#8217;ll try to show how a more advanced Zend Framework <strong>error controller</strong> could be implemented to help developers tackle errors quickly.</p>
<pre name="code" class="php:nogutter">
class ErrorController extends Zend_Controller_Action
{
    private $_notifier;
    private $_error;
    private $_environment;

    public function init()
    {
        parent::init();

        $bootstrap = $this->getInvokeArg('bootstrap');

        $environment = $bootstrap->getEnvironment();
        $error = $this->_getParam('error_handler');
        $mailer = new Zend_Mail();
        $session = new Zend_Session_Namespace();
        $database = $bootstrap->getResource('Database');
        $profiler = $database->getProfiler();

        $this->_notifier = new Application_Service_Notifier_Error(
            $environment,
            $error,
            $mailer,
            $session,
            $profiler,
            $_SERVER
        );

        $this->_error = $error;
        $this->_environment = $environment;
   }

    public function errorAction()
    {
        switch ($this->_error->type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->message = 'Page not found';
                break;

            default:
                $this->getResponse()->setHttpResponseCode(500);
                $this->_applicationError();
                break;
        }

        // Log exception, if logger available
        if ($log = $this->_getLog()) {
            $log->crit($this->view->message, $this->_error->exception);
        }
    }

    private function _applicationError()
    {
        $fullMessage = $this->_notifier->getFullErrorMessage();
        $shortMessage = $this->_notifier->getShortErrorMessage();

        switch ($this->_environment) {
            case 'live':
                $this->view->message = $shortMessage;
                break;
            case 'test':
                $this->_helper->layout->setLayout('blank');
                $this->_helper->viewRenderer->setNoRender();

                $this->getResponse()->appendBody($shortMessage);
                break;
            default:
                $this->view->message = nl2br($fullMessage);
        }

        $this->_notifier->notify();
    }

    private function _getLog()
    {
        $bootstrap = $this->getInvokeArg('bootstrap');
        if (!$bootstrap->hasPluginResource('Log')) {
            return false;
        }
        $log = $bootstrap->getResource('Log');
        return $log;
    }
}
</pre>
<p>The modified error controller is aware of the environment it is running in. It&#8217;s likely that depending on the environment you would want to display different layouts with different information. For example while debugging Zend Controller Tests you may want to reduce the amount of HTML appearing in your terminal screen by disabling the layout while running in the test environment. You&#8217;ll also notice the Application_Service_Notifier_Error class dependency. This class is responsible for deciding whether to send an email to the developers and gathers potentially helpful information from different sources. You&#8217;ll also notice how the dependencies for the notifier are instantiated. It can be done in different ways using <strong>dependency injection</strong> frameworks, using <strong>bootstrap resources</strong> and so on. It&#8217;s up to you to decide what fits your application better.</p>
<pre name="code" class="php:nogutter">
class Application_Service_Notifier_Error
{
    protected $_environment;
    protected $_mailer;
    protected $_session;
    protected $_error;
    protected $_profiler;

    public function __construct(
        $environment,
        ArrayObject $error,
        Zend_Mail $mailer,
        Zend_Session_Namespace $session,
        Zend_Db_Profiler $profiler,
        Array $server)
    {
        $this->_environment = $environment;
        $this->_mailer = $mailer;
        $this->_error = $error;
        $this->_session = $session;
        $this->_profiler = $profiler;
        $this->_server = $server;
    }

    public function getFullErrorMessage()
    {
        $message = '';

        if (!empty($this->_server['SERVER_ADDR'])) {
            $message .= "Server IP: " . $this->_server['SERVER_ADDR'] . "\n";
        }

        if (!empty($this->_server['HTTP_USER_AGENT'])) {
            $message .= "User agent: " . $this->_server['HTTP_USER_AGENT'] . "\n";
        }

        if (!empty($this->_server['HTTP_X_REQUESTED_WITH'])) {
            $message .= "Request type: " . $this->_server['HTTP_X_REQUESTED_WITH'] . "\n";
        }

        $message .= "Server time: " . date("Y-m-d H:i:s") . "\n";
        $message .= "RequestURI: " . $this->_error->request->getRequestUri() . "\n";

        if (!empty($this->_server['HTTP_REFERER'])) {
            $message .= "Referer: " . $this->_server['HTTP_REFERER'] . "\n";
        }

        $message .= "Message: " . $this->_error->exception->getMessage() . "\n\n";
        $message .= "Trace:\n" . $this->_error->exception->getTraceAsString() . "\n\n";
        $message .= "Request data: " . var_export($this->_error->request->getParams(), true) . "\n\n";

        $it = $this->_session->getIterator();

        $message .= "Session data:\n\n";
        foreach ($it as $key => $value) {
            $message .= $key . ": " . var_export($value, true) . "\n";
        }
        $message .= "\n";

        $query = $this->_profiler->getLastQueryProfile()->getQuery();
        $queryParams = $this->_profiler->getLastQueryProfile()->getQueryParams();

        $message .= "Last database query: " . $query . "\n\n";
        $message .= "Last database query params: " . var_export($queryParams, true) . "\n\n";

        return $message;
    }

    public function getShortErrorMessage()
    {
        $message = '';

        switch ($this->_environment) {
            case 'live':
                $message .= "It seems you have just encountered an unknown issue.";
                $message .= "Our team has been notified and will deal with the problem as soon as possible.";
                break;
            default:
                $message .= "Message: " . $this->_error->exception->getMessage() . "\n\n";
                $message .= "Trace:\n" . $this->_error->exception->getTraceAsString() . "\n\n";
        }

        return $message;
    }

    public function notify()
    {
        if (!in_array($this->_environment, array('live', 'stage'))) {
            return false;
        }

        $this->_mailer->setFrom('do-not-reply@domain.com');
        $this->_mailer->setSubject("Exception on Application");
        $this->_mailer->setBodyText($this->getFullErrorMessage());
        $this->_mailer->addTo('alerts@domain.com');

        return $this->_mailer->send();
    }
}
</pre>
<p>This class provides an extensive report providing helpful details in what state the application was when an exception occurred. What&#8217;s the IP address of the server (maybe the application is distributed on many servers), what was the time, was it an AJAX request, what was user&#8217;s session data, request data.</p>
<p>One of the nice things to have is to be able to tell what was the last database query executed. This is especially useful if some dynamic database query fails or someone is trying to make an SQL injection. The easiest way to achieve this is to use a <a href="http://framework.zend.com/manual/en/zend.db.profiler.html">Zend_Db_Profiler</a>. But the default profiler consumes a lot of server resources and should not be enabled on production environments. To work around this we use a custom dummy profiler that does no profiling at all and just stores the last query information in memory.</p>
<pre name="code" class="php:nogutter">
class Application_Db_Profiler extends Zend_Db_Profiler
{
    protected $_lastQueryText;
    protected $_lastQueryType;

    public function queryStart($queryText, $queryType = null)
    {
        $this->_lastQueryText = $queryText;
        $this->_lastQueryType = $queryType;

        return null;
    }

    public function queryEnd($queryId)
    {
        return;
    }

    public function getQueryProfile($queryId)
    {
        return null;
    }

    public function getLastQueryProfile()
    {
        $queryId = parent::queryStart($this->_lastQueryText, $this->_lastQueryType);

        return parent::getLastQueryProfile();
    }
}
</pre>
<p>The <strong>custom error controller</strong> will only notify developers of errors that occur on production and stage environments to avoid spamming people with exceptions from the unstable development environment. The <em>Application_Service_Notify_Error</em> class is also highly testable. All the dependencies can be mocked, no global variables or constants are used. The class itself could be more refined by employing polymorphism instead of <em>if</em> statements but I believe it&#8217;s better to keep the example simple to make it easily understandable.</p>
<p>Depending on which version of the Zend Framework is being used the implementation for the custom error controller may be a little different, but the general idea is the same. In short the advanced error controller provides additional information such as session data, database queries, server variables and also is capable of notifying developers when errors occur on production or stage environments. Please let me know if this is helpful by providing feedback in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/custom-profiler-for-live-environments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Avoiding Brittle Tests / Testing Output</title>
		<link>http://www.thedeveloperday.com/avoiding-brittle-tests-testing-output/</link>
		<comments>http://www.thedeveloperday.com/avoiding-brittle-tests-testing-output/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 00:22:22 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[functional]]></category>
		<category><![CDATA[unit]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=517</guid>
		<description><![CDATA[While unit tests have benefits they can also cause trouble. Having tests to catch software bugs is great but having tests that break whenever the application is at least slightly changed might not be very pleasant. The latter effect is called brittle tests. It may work well for applications which change rarely but may be [...]]]></description>
			<content:encoded><![CDATA[<p>While <strong>unit tests</strong> have benefits they can also cause trouble. Having tests to catch software bugs is great but having tests that break whenever the application is at least slightly changed might not be very pleasant. The latter effect is called <strong>brittle tests</strong>. It may work well for applications which change rarely but may be counterproductive for applications that change rapidly. <strong>Test brittleness</strong> can be caused by a variety of implementation details. This post aims to describe few of these details and explain ways how brittle tests can be avoided.</p>
<h2>Deciding how detailed the tests should be</h2>
<p>It&#8217;s important to have an at least general idea what tests should test and what should be left untested. Imagine having to <strong>functional test</strong> a web application UI displaying a form made of various input fields populated with values coming from the database. Quite a few things could be tested. Are all the values displayed? Are all radios, check boxes, drop-downs properly selected? Are validation messages displayed and are they correct? Are all labels displayed and correct? Are attached javascript events working? Can the form be submitted and is the data passed to the underlying layer? Is the confirmation message displayed?</p>
<p>The more things there are to test more likely that the tests will break not because of a bug but of a minor change. It&#8217;s important to pick only the important battles to fight. Even though it&#8217;s possible to test a lot of things it may not be practical to do so. It would certainly be possible to run a spelling checker on every displayed word but if it&#8217;s not critical to the application it may not be worthwhile to do so. For example <strong>testing javascript integration</strong> requires use of <a href="http://seleniumhq.org/">Selenium</a>. To work with continuous building it would require a <a href="http://seleniumhq.org/projects/remote-control/">Selenium RC</a> server to run all the browsers. Tests recorded by a selenium recorder may be brittle to a slightest HTML structure change unless designed very carefully. While selenium would provide the ultimate <strong>functional testing</strong> power it might be overkill for a simple web application. Decide what is critical to your application, which things are more likely to break than others and test those things only. Adapt to <strong>reoccurring software problems</strong> by adding additional tests.</p>
<h2>Testing output not implementation</h2>
<p>When developing <strong>unit tests</strong> the most effective way to test is by testing the output of method calls instead of testing the internal implementation. For example testing a simple multiplication function which multiplies <em>a</em> and <em>b</em> is straightforward. More sophisticated units which rely on other units require use of <strong>mocks</strong>. If possible it&#8217;s best to avoid testing that a mock was used or how many times a mock was called and what kind of data it was passed. Otherwise the test is tightly hooked to the internal implementation and is more likely to break when it changes. It comes to the first principle deciding how detailed a test should be. If you are fairly comfortable that the code is less likely to change or break or it&#8217;s less critical, hooking deep into the mocks might be avoided. Imagine having to test the following piece of code:</p>
<pre name="code" class="php:nogutter">
class Notifier
{
    public function __construct(Zend_Mail $mailer)
    {
        $this->_mailer = $mailer;
    }

    public function notify()
    {
        $this->_mailer->setBodyText('This is the text of the mail.');
        $this->_mailer->setFrom('somebody@example.com', 'Some Sender');
        $this->_mailer->addTo('someone@example.com', 'Some Recipient');
        $this->_mailer->setSubject('TestSubject');
        return $this->_mailer->send();
    }
}
</pre>
<p>In this case the mock is the <em>_mailer</em>. All it&#8217;s method calls could be mocked and tested against that they are called only once and are passed the correct data. In turn that would make the test more likely to break whenever this function is changed. Instead it may be enough to test that function <em>notify()</em> returns true whenever <em>send()</em> returns true. On other hand such a test might seem not sufficient enough and more hooks may be required. For example adding a test for <em>addTo()</em> function call. Or if the functionality is extremely critical an integration test could be created to test that an actual message was sent to the mail server with the correct header and body.</p>
<h2>Final Words</h2>
<p>In the end it&#8217;s a challenge of trying to find the the acceptable balance between <strong>testing application functionality</strong> and avoiding having too <strong>many brittle tests</strong>. Try to identify what&#8217;s important to your application, and test those things only, prefer <strong>testing output</strong> of method calls over hooking deeply into implementation. Let your tests work for you and not against you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/avoiding-brittle-tests-testing-output/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Anti Patterns</title>
		<link>http://www.thedeveloperday.com/php-anti-patterns/</link>
		<comments>http://www.thedeveloperday.com/php-anti-patterns/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 13:40:40 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[antipatterns]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=572</guid>
		<description><![CDATA[Another talk I&#8217;ve atended at PHPUK 2010 was AntiPHPatterns by Stefan Priebsch. While design patterns are core implementation independent solutions to problems that occur over and over again which also serve as a great vocabulary, anti patterns are software patterns that are ineffective or counterproductive. In his presentation Stefan describes some of these anti patterns:
1. Constantitis. Excessive use [...]]]></description>
			<content:encoded><![CDATA[<p>Another talk I&#8217;ve atended at <a href="http://www.phpconference.co.uk/">PHPUK 2010</a> was <a href="http://www.slideshare.net/spriebsch/antiphpatterns-php-uk-conference-2010">AntiPHPatterns</a> by <a href="http://priebsch.de/blog/">Stefan Priebsch</a>. While <strong>design patterns</strong> are core implementation independent solutions to problems that occur over and over again which also serve as a great vocabulary, <strong>anti patterns</strong> are software patterns that are ineffective or counterproductive. In his presentation Stefan describes some of these anti patterns:</p>
<p>1. <strong>Constantitis</strong>. Excessive use of global constants is considered to be a <strong>code smell</strong>. Global constants can be defined anywhere in the code base, there is a risk of name clashes if a constant is already defined, <strong>global constants</strong> make the code more coupled, testing gets more complicated since constants have to be known beforehand and defined explicitly which might be even more troubling if a constant has to change it&#8217;s value for another test. Since class constants are not global it&#8217;s OK to use them. Cure for constantitis is not to use global constants and instead use <strong>dependency injection</strong>.</p>
<p>2. <strong>Globalomania</strong>. Global variables share the same problems as global constants. Because <strong>global variables</strong> can be changed it makes them more dangerous than global constants since a change in one part of the codebase can affect the other without anyone noticing. Global variables can be cured by using <strong>dependency injection</strong>.</p>
<p>3. <strong>Singletonitis</strong>. Singleton is one of the most popular design patterns. It&#8217;s wide success is due to the fact that singletons by implementation are available globally in the entire application. The problem that <strong>singleton design pattern</strong> tries to solve is to prevent having multiple instances of the same class. This is rarely the problem in most applications and most singletons are being used as global variables instead. Singletons share the same problems as global constants and global variables and therefore should be avoided. Singletonitis has the same cure as constantitis and globalomania.</p>
<p>4. <strong>God classes</strong>. According to <strong>object oriented</strong> <strong>best practices</strong> classes should do one thing only and do it well. Classes should be refined and granular. One of the ways to think about this is to ask yourself what are the responsibilities of this class. In an ideal case you will be able to describe it in one sentence without any &#8220;and&#8217;s&#8221;. When classes start having too many  responsibilities they become <strong>god classes</strong>. Usually the whole application relies on one of the god classes which makes the application tight coupled and therefore more <strong>difficult to maintain</strong>. To cure god classes minimize <strong>class responsibilities</strong> so that objects know everything about themselves and little about others.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/php-anti-patterns/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lost Art of Simplicity PHP UK 2010</title>
		<link>http://www.thedeveloperday.com/lost-art-of-simplicity-php-uk-2010/</link>
		<comments>http://www.thedeveloperday.com/lost-art-of-simplicity-php-uk-2010/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 00:08:08 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[Rant]]></category>
		<category><![CDATA[phpuk]]></category>
		<category><![CDATA[simplicity]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=565</guid>
		<description><![CDATA[Lost Art of Simplicity by Josh Holmes was the keynote talk at the PHP UK 2010 conference. I found it to be an interesting talk with lots of good advice. While listening to Josh I was able to identify myself in the past participating in all the common software development pitfalls. I would like to share [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.joshholmes.com/blog/2009/04/29/TheLostArtOfSimplicity.aspx">Lost Art of Simplicity by Josh Holmes</a> was the keynote talk at the <a href="http://www.phpconference.co.uk/">PHP UK 2010 conference</a>. I found it to be an interesting talk with lots of good advice. While listening to Josh I was able to identify myself in the past participating in all the common software development pitfalls. I would like to share what I consider to be at least some of the most important points from the talk:</p>
<ol>
<li> <strong>Work with your users. Focus on them and their exact needs</strong>. As developers we often tend to forget that actual users will be using our systems. We should stop and think is what we&#8217;re doing going to fulfill the actual needs of our users.</li>
<li><strong>When deciding which tools to use for a particular problem or a project always carefully weigh all the benefits and downsides to pick the best tools for the job.</strong> If for example most of your company&#8217;s software is written in PHP and is using MySQL doesn&#8217;t necessarily mean that you should keep doing so. It might be that another language such as <a href="http://www.python.org">Python</a> or another type of a data store such as <a href="http://couchdb.apache.org/">CouchDB</a> might be a better choice for your next project. Developers also like to play with new shiny experimental toys but it doesn&#8217;t mean that it&#8217;s the best idea for your company to use it for a particular problem.</li>
<li><strong>Do the simplest thing possible.</strong> As Albert Einstein once said &#8220;Things should be made as simple as possible, but not any simpler&#8221;. &#8220;Cleverness&#8221; might not always be a good solution. Complexity involves more moving parts and more possibilities for things to fail. As developers we tend to think about possible future developments. While it is good to do so it is also important not to over do it. While it may be reasonable to believe that a different caching mechanism might be used for a project that you work on it&#8217;s less likely that another database vendor will be used in the future.</li>
<li><strong>Invented here syndrome</strong>. It is very likely that any problem you will have will be already solved by many other people before you. If instead of inventing your own solution to the problem you can use someone else&#8217;s tools by all means do so. Not every tool might do exactly what you need, not every tool might seem trustworthy enough but there&#8217;s no excuse for not trying to find the best available tools.</li>
</ol>
<p>If you are interested to learn more take a look at <a href="http://www.joshholmes.com/blog/2009/04/29/TheLostArtOfSimplicity.aspx">Josh&#8217;s blog</a> where presentation slides and a full transcript is available.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/lost-art-of-simplicity-php-uk-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Expert Python Programming Review</title>
		<link>http://www.thedeveloperday.com/expert-python-programming-review/</link>
		<comments>http://www.thedeveloperday.com/expert-python-programming-review/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 21:39:15 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[Reviews]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=552</guid>
		<description><![CDATA[I&#8217;ve always been interested in Python. Python is a dynamic programming language with a very clear and readable syntax, strong introspection, intuitive object orientation and so on. It&#8217;s been used in many successful projects such as Trac, Django, Mercurial, YUM. It&#8217;s used in companies such as Google or Yahoo. Python has a vast standard library [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.thedeveloperday.com/wp-content/uploads/2010/02/python-book.png"><img class="size-full wp-image-554 alignleft" style="margin-right: 20px; margin-bottom: 20px;" title="python-book" src="http://www.thedeveloperday.com/wp-content/uploads/2010/02/python-book.png" alt="Expert Python Programming Book" width="100" height="123" /></a>I&#8217;ve always been interested in <a href="http://www.python.org/">Python</a>. Python is a dynamic programming language with a very clear and readable syntax, strong introspection, intuitive object orientation and so on. It&#8217;s been used in many successful projects such as <a href="http://trac.edgewall.org/">Trac</a>, <a href="http://www.djangoproject.com/">Django</a>, <a href="http://mercurial.selenic.com/">Mercurial</a>, <a href="http://fedoraproject.org/wiki/Tools/yum">YUM</a>. It&#8217;s used in companies such as Google or Yahoo. Python has a vast standard library allowing to solve almost any domain problem. From the early beginning Python had a <a href="http://python-history.blogspot.com/2009/01/pythons-design-philosophy.html">design philosophy</a> behind it which is probably one of the reasons why Python is such a successful programming language now days.</p>
<p>All these and other reasons make Python an interesting and valuable language to learn. I&#8217;ve chosen to review <a href="http://www.packtpub.com/expert-python-programming/book?utm_source=thedeveloperday.com&amp;utm_medium=bookrev&amp;utm_content=blog&amp;utm_campaign=mdb_002591">Expert Python Programming</a> as my next book. Having used Python for personal projects such as <a href="http://code.google.com/p/pydumpy/">PyDumpy</a> or work related tasks such as continuous integration with <a href="http://buildbot.net/trac">BuildBot</a> I hope it will be an interesting read that will help me to improve my understanding of Python.</p>
<p>For those interested Packt Publishing offers a <a href="http://www.packtpub.com/files/expert-python-programming-sample-chapter-chapter-10-documenting-your-project.pdf">sample chapter</a> of the book.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/expert-python-programming-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework Escaping Entities</title>
		<link>http://www.thedeveloperday.com/zend-framework-escaping-entities/</link>
		<comments>http://www.thedeveloperday.com/zend-framework-escaping-entities/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 00:41:10 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[entity]]></category>
		<category><![CDATA[escaping]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=537</guid>
		<description><![CDATA[Zend Framework has a powerful input filtering component Zend_Filter_Input. It provides an interface to define multiple filters and validators and apply them to a collection of data. By default values returned from Zend_Filter_Input are escaped for safe HTML output. An example of such functionality:

$validators = array(
    'id' => array(
    [...]]]></description>
			<content:encoded><![CDATA[<p>Zend Framework has a powerful input filtering component <a href="http://framework.zend.com/manual/en/zend.filter.input.html">Zend_Filter_Input</a>. It provides an interface to define multiple filters and validators and apply them to a collection of data. By default values returned from Zend_Filter_Input are escaped for safe HTML output. An example of such functionality:</p>
<pre name="code" class="php:nogutter">
$validators = array(
    'id' => array(
        'digits',
        'allowEmpty' => true,
    ),
    'name' => array(
        'presence' => 'required',
        new Zend_Validate_StringLength(5, 255),
    ),
    'date' => array(
        'presence' => 'required',
        new Zend_Validate_Date('d/m/Y'),
    ),
);

$filters = array(
    '*'  => 'StringTrim',
);

$input = new Zend_Filter_Input($filters, $validators, $data);

if ($input->isValid()) {
    print_r($input->getEscaped());
} else {
    print_r($input->getMessages());
}
</pre>
<p>The code above validates the <em>$data</em> array by checking that the id key consists only of digits or is empty, that name is present and it&#8217;s min length is 5 and max length is 255 and that date is present and it&#8217;s format is <em>d/m/Y</em>. The StringTrim validator removes any spaces in front and at the end of all the <em>$data</em> values. If the <em>$data</em> array is valid all escaped values are outputted and if not a generated list of error messages is presented.</p>
<p>Recently I&#8217;ve ran into a small problem while using Zend_Input_Filter. According to the <strong>best security practices</strong> all data coming from the user should be escaped before being outputted to the screen. This also means data coming from a database. This requires to escape every single output statement in every view. In my opinion this adds unwanted verbosity, performance overhead and a possibility to easily miss that something was not escaped in one of the views. That is why if there is a possibility I would prefer to trust the database and not worry about the data incoming from it. It may not be a very good option if data in the database is most often presented in other documents than HTML. Since all values would need to be decoded which defeats the whole purpose. Though this is rarely the case.</p>
<p>By default Zend_Filter_Input escapes values by using the <a href="http://uk3.php.net/htmlentities">htmlentities</a> function. Which converts all applicable characters to HTML entities. This means that for example Danish language characters Æ Ø Å would be stored as &amp;AElig; &amp;Oslash; &amp;Aring; Which means that it would take 7 bytes on average to store a single letter that otherwise could be stored using 1 &#8211; 3 bytes using UTF-8 encoding support in MySQL. This could also potentially ruin collation sorting.</p>
<p>To overcome this issue a very similar function <a href="http://uk3.php.net/htmlspecialchars">htmlspecialchars</a> could be used. It escapes only a few certain characters such as &gt; &lt; &#8221; without escaping all international characters. The actual problem with Zend_Filter_Input is that it does not have an escape filter that uses htmlspecialchars. To solve the issue I&#8217;ve created a copy of HtmlEntities filter which uses htmlspecialchars function instead.</p>
<p>The filter can then be used like this:</p>
<pre name="code" class="php:nogutter">
$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setDefaultEscapeFilter(new Company_Product_Filter_HtmlSpecialChars());
</pre>
<p>Zend_Filter_Input is a great tool to ease form validation and filtering. I would be very interested to hear from you how this problem could be solved.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/zend-framework-escaping-entities/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP London Conference 2010</title>
		<link>http://www.thedeveloperday.com/php-london-conference-2010/</link>
		<comments>http://www.thedeveloperday.com/php-london-conference-2010/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 15:36:57 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[london]]></category>
		<category><![CDATA[phpnw]]></category>
		<category><![CDATA[phpuk]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=538</guid>
		<description><![CDATA[I&#8217;m pleased to say that I will be attending the PHP UK conference 2010 in London. Last year I attended PHPNW 2009 which was great and I hope PHP London to be even better. It will be certainly interesting to listen to famous PHP speakers such as Stefan Priebsch, Fabien Potencier author of Symfony. The [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pleased to say that I will be attending the <a href="http://www.phpconference.co.uk/">PHP UK conference 2010</a> in London. Last year I attended <a href="http://www.thedeveloperday.com/phpnw09-conference/">PHPNW 2009</a> which was great and I hope PHP London to be even better. It will be certainly interesting to listen to famous PHP speakers such as <a href="http://priebsch.de/">Stefan Priebsch</a>, <a href="http://fabien.potencier.org/">Fabien Potencier</a> author of Symfony. The conference schedule has been announced and these are the talks that I&#8217;m going to attend:</p>
<ul>
<li>The lost art of simplicity</li>
<li>AntiPHPatterns</li>
<li>PHP 5.3 in practice</li>
<li>PHPillow &amp; CouchDB &amp; PHP</li>
<li>&#8216;In search of&#8230;&#8217; &#8211; integrating site search systems</li>
<li>PHP on the D-BUS</li>
</ul>
<p>The keynote talk about lost art of simplicity sounds very promising. Also very eager to see Fabien&#8217;s presentation on how PHP 5.3 can be used in practice.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/php-london-conference-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework Database Profiler Reporting</title>
		<link>http://www.thedeveloperday.com/zend-framework-database-profiler-reporting/</link>
		<comments>http://www.thedeveloperday.com/zend-framework-database-profiler-reporting/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 19:20:24 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[profiler]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=434</guid>
		<description><![CDATA[Zend Framework has a powerful Database Profiler component. It is remarkably simple to integrate the database profiler with the Zend Framework front controller with the use of Firefox addons FireBug and FirePHP:
// In your bootstrap file

$profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);

// Attach the profiler to your db adapter
$db->setProfiler($profiler);
Or just by enabling it in the database [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zendframework.com">Zend Framework</a> has a powerful <a href="http://framework.zend.com/manual/en/zend.db.profiler.html">Database Profiler</a> component. It is remarkably simple to integrate the database profiler with the Zend Framework front controller with the use of <a href="http://www.firefox.com">Firefox</a> addons <a href="https://addons.mozilla.org/en-US/firefox/addon/1843">FireBug</a> and <a href="http://www.firephp.org/">FirePHP</a>:</p>
<pre name="code" class="php:nogutter">// In your bootstrap file

$profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);

// Attach the profiler to your db adapter
$db->setProfiler($profiler);</pre>
<p>Or just by enabling it in the database configuration:</p>
<pre name="code" class="php:nogutter">$db = array(
    'type' => 'pdo_mysql',
    'host' => 'localhost',
    'dbname' => 'dbname',
    'username' => 'username',
    'password' => 'password',
    'profiler' => array(
        'enabled' => true,
        'class' => 'Zend_Db_Profiler_Firebug',
    )
);</pre>
<p>Producing nicely formatted results:</p>
<p><a href="http://www.thedeveloperday.com/wp-content/uploads/2010/02/firebug-profiler.png"><img class="alignnone size-full wp-image-522" title="Firebug Zend Framework Db Profiler" src="http://www.thedeveloperday.com/wp-content/uploads/2010/02/firebug-profiler.png" alt="" width="550" height="201" /></a></p>
<p>Firebug profiler is great tool. But it requires to use Firefox and have FireBug and FirePHP addons installed. Not everyone in your organization may be Firefox users or have these addons installed. Another drawback is that sometimes queries may be quite big and complex. It&#8217;s not easy to analyse them in a Firebug window or to copy them to an editor that supports SQL highlighting.</p>
<p>To solve that it is possible to create a custom database profiler reporting mechanism. To output the profiler queries I&#8217;ll create a custom Zend Framework action helper:</p>
<pre name="code" class="php:nogutter">
class Company_Product_Helper_Profiler extends Zend_Controller_Action_Helper_Abstract
{
    protected $_profiler;
    protected $_view;
    protected $_config;
    protected $_db;

    public function __construct(Zend_Config $config, $db)
    {
        $this->_config = $config;
        $this->_db = $db;
    }

    public function init()
    {
        $this->_view = new Zend_View();

        parent::init();
    }

    public function postDispatch()
    {
        $this->_profiler = new Company_Product_Db_Profiler_Report($this->_db1);

        if (!$this->_isProfilerEnabled()) {
            return false;
        }

        $this->outputToScreen();
    }

    protected function _isProfilerEnabled()
    {
        if ($this->_config->environment == 'live') {
            return false;
        }

        if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) {
            return false;
        }

        $profiler = $this->getRequest()->getParam('profiler');

        if (!empty($profiler)) {
            return true;
        }

        return false;
    }

    protected function outputToScreen()
    {
        $this->_view->headLink()->appendStylesheet('/css/highlight/default.css', 'screen');

        $this->_view->headScript()->appendFile('/js/highlight.pack.js');
        $this->_view->headScript()->appendScript('
            hljs.tabReplace = \'    \';
            hljs.initHighlightingOnLoad();
        ');

        $this->getResponse()->appendBody($this->_profiler);
    }
}
</pre>
<p>The <strong>action helper</strong> uses a <strong>post dispatch hook</strong>. The post dispatch hook is called after the <strong>Zend Framework</strong> dispatcher dispatches a request. A post dispatch hook is used to ensure that all queries have been run and to integrate the profiler with the Front Controller without changing any of the controller classes.</p>
<p>Action helper profiler checks to see if any profiling information should be outputted. It checks if the current configuration environment is not production to not allow unauthorized people to use the profiler. It also checks if a request is not an AJAX request, since AJAX requests may be returning JSON data structures and any additional output can break the client which sent the request. Profiler can be enabled by adding a URL query parameter <strong>?profiler=1</strong>.</p>
<p>To highlight the SQL queries profiler uses a third party JavaScript highlighting library <a href="http://softwaremaniacs.org/soft/highlight/en/">Highlight.js</a>. On page load highlight.js finds all &lt;code&gt; nodes in the DOM structure, detects the programming or markup language type of the content inside them and highlights it.</p>
<p>The profiler action helper also uses another class to format the profiler report. The profiler report class implements an iterator interface and the __toString method allowing to use it in different ways. It could also be used to format profiler output for environments such as terminals which can&#8217;t interpret HTML.</p>
<pre name="code" class="php:nogutter">
class Company_Product_Db_Profiler_Report implements Iterator
{
    protected $_profiler;
    protected $_html = false;
    protected $_position ;

    public function __construct($db, $html = true)
    {
        $this->_profiler = $db->getProfiler();
        $this->_html = $html;
        $this->_position = 0;
        $this->_profiles = $this->_profiler->getQueryProfiles();
    }

    public function setOutputFormatToHtml($value)
    {
        $this->_html = !empty($value);
    }

    public function __toString()
    {
        $out = "";

        if ($this->_html) {
            foreach ($this->_profiles as $key => $query) {
                $out .= $this->_formatProfileAsHtml($key, $query);
            }
        } else {
            foreach ($this->_profiles as $key => $query) {
                $out .= $this->_formatProfileAsText($key, $query);
            }
        }

        return $out;
    }

    protected function _formatProfileAsHtml($key, $query)
    {
        $out = "&lt;pre&gt;&lt;code&gt;{$key}. " . wordwrap($query->getQuery(), 150) . "\n\n ({$query->getElapsedSecs()} s.) &lt;/code&gt; &lt;/pre&gt;";
        return $out;
    }

    protected function _formatProfileAsText($key, $query)
    {
        $out = "$key. {$query->getQuery()} ({$query->getElapsedSecs()} s.)\n\n";
        return $out;
    }

    public function rewind()
    {
        $this->_position = 0;
    }

    public function current()
    {
        if ($this->_html) {
            return $this->_formatProfileAsHtml($this->_position, $this->_profiles[$this->_position]);
        } else {
            return $this->_formatProfileAsText($this->_position, $this->_profiles[$this->_position]);
        }
    }

    public function key()
    {
        return $this->_position;
    }

    public function next()
    {
        ++$this->_position;
    }

    public function valid()
    {
        return isset($this->_profiles[$this->_position]);
    }
}
</pre>
<p>To make Zend Framework aware of the profiler action helper add the following lines of code to the bootstrap file:</p>
<pre name="code" class="php:nogutter">Zend_Controller_Action_HelperBroker::addHelper(
    new Company_Product_Helper_Profiler($config, $databaseConnection)
);</pre>
<p>When done the output of the profiler should look something like this:</p>
<p><a href="http://www.thedeveloperday.com/wp-content/uploads/2010/02/sql-profiler.png"><img src="http://www.thedeveloperday.com/wp-content/uploads/2010/02/sql-profiler.png" alt="" title="sql profiler" width="551" height="201" class="alignnone size-full wp-image-530" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/zend-framework-database-profiler-reporting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subversion Self Signed Certificates</title>
		<link>http://www.thedeveloperday.com/subversion-self-signed-certificates/</link>
		<comments>http://www.thedeveloperday.com/subversion-self-signed-certificates/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 17:37:19 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[certificate]]></category>
		<category><![CDATA[self-signed]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=433</guid>
		<description><![CDATA[When connecting to Subversion repositories using SSL connections the SVN client checks the server certificate if it is not expired, if it&#8217;s host description matches the host of the repository and if the authority which signed the certificate is trusted.
If the certificate fails to comply with any of the above rules the SVN client will [...]]]></description>
			<content:encoded><![CDATA[<p>When connecting to <strong>Subversion</strong> repositories using <strong>SSL</strong> connections the SVN client checks the <strong>server certificate</strong> if it is not expired, if it&#8217;s host description matches the host of the repository and if the authority which signed the certificate is trusted.</p>
<p>If the <strong>certificate</strong> fails to comply with any of the above rules the SVN client will respond with a message such as this one:</p>
<blockquote style="background: #444; color: #fff; padding-left: 2px;"><p>Error validating server certificate for &#8216;https://hostname:443&#8242;:<br />
 &#8211; The certificate is not issued by a trusted authority. Use the<br />
   fingerprint to validate the certificate manually!<br />
Certificate information:<br />
 &#8211; Hostname: hostname<br />
 &#8211; Valid: from Tue, 16 Feb 2010 16:58:39 GMT until Fri, 14 Feb 2020 16:58:39 GMT<br />
 &#8211; Issuer: company.com, London, Berkshire, GB<br />
 &#8211; Fingerprint: d5:4e:d8:12:33:12:a5:f1:18:91:77:40:c4:77:3b:0b:f8:51:71:cd<br />
(R)eject, accept (t)emporarily or accept (p)ermanently?</p></blockquote>
<p>The certificate can still be accepted permanently manually. It may not be a solution if SVN commands are issued by non <strong>interactive processes</strong>. For example a PHP script run by apache trying to export a branch from the repository.</p>
<p>Certificates signed by trusted authorities such as Verisign should not have any problems. But <strong>self signed certificates</strong> will not be recognized by the SVN client which in turn will respond with the response above. Self signed certificates can be be made trusted by the SVN client by using the <strong>ssl-authority-files</strong> configuration option:</p>
<blockquote style="background: #444; color: #fff; padding-left: 2px;"><p>ssl-authority-files = /home/void/.subversion/company.crt</p></blockquote>
<p>The configuration file named <strong>servers</strong> which holds this configuration option can be stored in multiple locations on the filesystem. First the Subversion client will try to look for it in the home folder of the user that is executing the SVN command. Users such as <strong>apache</strong> will most likely not have a home folder. In such cases SVN tries to look for the servers file in the <strong>/etc/subversion</strong> directory. It may or may not exist depending on the OS distribution flavour. For example it exits on Ubuntu but does not exist on <strong>CentOS</strong> a flavour of <strong>RedHat</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/subversion-self-signed-certificates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting services in a clean environment</title>
		<link>http://www.thedeveloperday.com/starting-services-in-a-clean-environment/</link>
		<comments>http://www.thedeveloperday.com/starting-services-in-a-clean-environment/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 22:35:50 +0000</pubDate>
		<dc:creator>Žilvinas Šaltys</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[redhat]]></category>
		<category><![CDATA[services]]></category>

		<guid isPermaLink="false">http://www.thedeveloperday.com/?p=482</guid>
		<description><![CDATA[I was working on a small web application that creates Subversion branches and tags. In short it just executes SVN commands on the repository. Whenever a user executes an SVN command the SVN client tries to check user&#8217;s local home folder for the .subversion configuration directory. The issue that I was running into was that [...]]]></description>
			<content:encoded><![CDATA[<p>I was working on a small web application that creates Subversion branches and tags. In short it just executes SVN commands on the repository. Whenever a user executes an SVN command the SVN client tries to check user&#8217;s local home folder for the <strong>.subversion</strong> configuration directory. The issue that I was running into was that for some reason apache&#8217;s home folder was pointing to our system&#8217;s administrator <strong>home folder</strong> which in turn would result in a <strong>permission denied</strong> error when apache would try to access the .subversion folder.</p>
<p>It just didn&#8217;t make any sense. Turns out if you start a service through <strong>/etc/init.d/</strong> it starts that service with environment variables belonging to the user that started the service. In this case our system&#8217;s administrator started the service using his own user.</p>
<p>To start services in a clean environment a special utility called <strong>service</strong> should be used. It usually resides in the <strong>/sbin</strong> directory. So for example instead of starting apache like this:</p>
<blockquote style="background: #444; color: #fff; padding-left: 2px;"><p><em>$ sudo /etc/init.d/httpd start</em></p></blockquote>
<p>It should be started like this:</p>
<blockquote style="background: #444; color: #fff; padding-left: 2px;"><p><em>$ sudo /sbin/service httpd start</em></p></blockquote>
<p>Which will result in <strong>$HOME</strong> <strong>environment variable</strong> being empty and the SVN client not getting a <strong>permission denied</strong> error.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedeveloperday.com/starting-services-in-a-clean-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
