<?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>Coderholic &#187; PHP</title>
	<atom:link href="http://www.coderholic.com/category/programming/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coderholic.com</link>
	<description>Addicted to Development</description>
	<lastBuildDate>Tue, 31 Aug 2010 09:19:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>8 Reasons Why You Should Try Django</title>
		<link>http://www.coderholic.com/8-reasons-why-you-should-try-django/</link>
		<comments>http://www.coderholic.com/8-reasons-why-you-should-try-django/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 22:14:36 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web dev]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=336</guid>
		<description><![CDATA[I have been using Python for quite a few years, but mostly for writing one off sysadmin scripts, command line utilities, and of course PyRadio. Most of my web development work has been done with PHP. The language gets a lot of bad press, some deserved and some not so much. I&#8217;ve had my own [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-505 aligncenter" title="django" src="http://www.coderholic.com/wp-content/uploads/django1.png" alt="django" width="500" height="228" /></p>
<p>I have been using Python for quite a few years, but mostly for writing one off sysadmin scripts, command line utilities, and of course <a href="http://www.coderholic.com/pyradio">PyRadio</a>. Most of my web development work has been done with PHP. The language gets a lot of bad press, some deserved and some not so much. I&#8217;ve had my own <a href="http://www.coderholic.com/beware-phps-split/">gripes</a>, but all-in-all I&#8217;ve been fairly happy with PHP.</p>
<p>Several months ago, though, I thought I&#8217;d give <a href="http://www.djangoproject.com/">Django</a> a try, a python based web framework. I was completely blown away!  Compared to the PHP frameworks I&#8217;d worked with, such as <a href="http://cakephp.org/">Cake</a>, it was just so much more of a pleasure to work with. So here are 8 reasons why you should give Django a try yourself if you haven&#8217;t already. You won&#8217;t be disappointed!</p>
<p><strong>1. Great Documentation</strong></p>
<p>The Django documentation is well written, extremely comprehensive, and up to date. The <a href="http://docs.djangoproject.com/en/">official documentation</a> contains details API references, loads of relevant examples, and tutorials for those getting started. If that isn&#8217;t enough there&#8217;s also a whole <a href="http://www.djangobook.com/">book</a> that&#8217;s available for free online.</p>
<p><strong>2. It&#8217;s Python</strong></p>
<p>The fact that it&#8217;s Python is a huge plus point for me. It&#8217;s a great language that doesn&#8217;t suffer from many of the well documented inconsistencies that PHP does, and includes some nice features such as decorators and first-class functions. Going back to PHP you soon start to miss the little things, such as the ability to assign <a href="http://diveintopython.org/native_data_types/declaring_variables.html#odbchelper.multiassign">multiple values at once</a>, and the simplicity of <a href="http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice">slicing lists</a>.</p>
<p><strong>3. The ORM</strong></p>
<p>Django&#8217;s object relational mapper completely abstracts away the database, meaning you don&#8217;t need to worry about your database schema or constructing SQL queries. If you&#8217;re using to writing SQL queries then the <a href="http://docs.djangoproject.com/en/dev/ref/models/querysets/">QuerySet</a> API takes a little getting used to, but it&#8217;s really worth the effort. Projects like <a href="http://south.aeracode.org/">South</a> make the ORM even more powerful, allowing you to make schema changes and data migrations automatically.</p>
<p><strong>4. Built in Development Server</strong></p>
<p>Where PHP really shines is on its ease of deployment. Setting up a local development server can be a bit of a pain though, especially if you&#8217;re working on several different sites. Django comes with a built in development server though, so you can be up and running within minutes! From your project&#8217;s root directory you just do</p>
<pre>./manage.py runserver</pre>
<p>and access your django website from http://localhost:8000 &#8211; awesome!</p>
<p><strong>5. The Admin Interface</strong></p>
<p>Django&#8217;s built-in admin interface is practically a full blown CMS, allowing you to add, delete or update your data. It&#8217;s pretty much all automatic, but it&#8217;s also fairly configuration. See the <a href="http://docs.djangoproject.com/en/dev/intro/tutorial02/">documentation</a> to see what it can do!</p>
<p><strong>6. Reusable Applications</strong></p>
<p>Django projects are broken up into &#8220;applications&#8221;, and there are lots of existing reusable applications that you can use for your own projects, such as those for <a href="http://code.google.com/p/django-registration/">user registration</a>, <a href="http://github.com/flashingpumpkin/django-socialregistration">facebook integration</a>, <a href="http://github.com/nathanborror/django-basic-apps">blogging</a>, and <a href="http://github.com/search?langOverride=&amp;language=&amp;q=django&amp;repo=&amp;start_value=2&amp;type=Repositories&amp;x=13&amp;y=19">many many more</a>.</p>
<p>Existing applications are great, but the whole project/application distinction also forces you to think about your own project structure and therefore more likely to make reusable components that you can use in more of your own projects, or even share for others to use.</p>
<p><strong>7</strong><strong>. Templates</strong></p>
<p>I&#8217;ve always been a bit dubious about the merits of PHP template engines such as Smarty. The Django template layer is great though. The inheritance model works well, and the restrictive language really forces you to have a very clean separation of presentation and logic.</p>
<p><strong>8</strong><strong>. Forms</strong></p>
<p>I usually find dealing with user input one of the most boring parts of web development. It takes time to get it right, and its repetitive. The Django Form API really simplifies things. You can define your form class, include and validation rules, and simply add a few lines to your template and few lines to your view and you&#8217;re done!</p>
<hr/>
<p>So those are my 8 reasons why you should give django a go. If you&#8217;re already a django user let me know if you have any points to add!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/8-reasons-why-you-should-try-django/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Faking late static binding in PHP</title>
		<link>http://www.coderholic.com/faking-late-static-binding-in-php/</link>
		<comments>http://www.coderholic.com/faking-late-static-binding-in-php/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 21:41:25 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=328</guid>
		<description><![CDATA[PHP 5.3 brings lots of long awaited features to the language, including closures, late static binding and namespaces. Unfortunately 5.3 still isn&#8217;t widely available, so some of us are stuck with older version of the language that lack these great new features. One feature I miss all the time is late static binding, or LSB. [...]]]></description>
			<content:encoded><![CDATA[<p>PHP 5.3 brings lots of long awaited features to the language, including closures, <a href="http://php.net/manual/en/language.oop5.late-static-bindings.php">late static binding</a> and namespaces. Unfortunately 5.3 still isn&#8217;t widely available, so some of us are stuck with older version of the language that lack these great new features.</p>
<p>One feature I miss all the time is late static binding, or LSB. The lack of LSB means that you can&#8217;t tell tell which class in your class hierarchy was invoked when calling a static method. Here&#8217;s a simple example:</p>
<pre name="code" class="php">
class class0 {
  public static function getName() {
      echo __CLASS__ . "\n";
  }
}

class class1 extends class0 {}

class class2 extends class1 {}

class0::getName(); // -> "class0"
class1::getName(); // -> "class0"
class2::getName(); // -> "class0"
</pre>
<p>Notice that all three method calls output &#8220;class0&#8243;, the name of the base class. There is no way to tell which class the static method was called on, and in some situations that is information we need to know. </p>
<p>So what can we do? One obvious solution is to re-implement the method in every subclass. This doesn&#8217;t pose much of a problem for a method as simple as the one in our example, but in reality our method is likely to be much more complex, and implementing it in every subclass will lead to lots of duplication. If we ever need to make changes to the method then changes will need to be made to every subclass too. Not fun!</p>
<p>And alternative solution is to have every subclass invoke the parent method, passing in the class name (or whatever variable we&#8217;re interested in). It requires only a couple of extra lines per subclass, rather than repeating the whole method. Any changes now only need to be made in one place. Here&#8217;s the code:</p>
<pre name="code" class="php">
class class0 {
  public static function getName($class = __CLASS__) {
      echo "$class\n";
  }
}

class class1 extends class0 {
  public static function getName($class = __CLASS__) {
      return parent::getName($class);
  }
}

class class2 extends class1 {
  public static function getName($class = __CLASS__) {
      return parent::getName($class);
  }
}

class0::getName(); // -> "class0"
class1::getName(); // -> "class1"
class2::getName(); // -> "class2"
</pre>
<p>In PHP5.3 we can use the new <a href="http://php.net/manual/en/function.get-called-class.php">get_called_class()</a>, so the code becomes much cleaner:</p>
<pre name="code" class="php">
class class0 {
  public static function getName() {
      echo get_called_class() . "\n";
  }
}

class class1 extends class0 {}

class class2 extends class1 {}

class0::getName(); // -> "class0"
class1::getName(); // -> "class1"
class2::getName(); // -> "class2"
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/faking-late-static-binding-in-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PHP Error Log Mail Script</title>
		<link>http://www.coderholic.com/php-error-log-mailscript/</link>
		<comments>http://www.coderholic.com/php-error-log-mailscript/#comments</comments>
		<pubDate>Tue, 26 May 2009 19:26:40 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=249</guid>
		<description><![CDATA[With the configuration option &#8220;log_errors&#8221; PHP will log all errors to the Apache error log file, allowing you to see all of the errors that have occurred while people have been using your site. Given the snippet of code below: &#60;?php // Ensure logging is enabled. Ideally this will be set in php.ini ini_set('log_errors', 'On'); [...]]]></description>
			<content:encoded><![CDATA[<p>With the configuration option &#8220;log_errors&#8221; PHP will log all errors to the Apache error log file, allowing you to see all of the errors that have occurred while people have been using your site. Given the snippet of code below:</p>
<pre name="code" class="php">
&lt;?php
	// Ensure logging is enabled. Ideally this will be set in php.ini
	ini_set('log_errors', 'On');
	// Call a non-existant function to generate an error
	doesNotExist();
?&gt;
</pre>
<p>You&#8217;ll see something like the following entry in the error log, which includes a description of the problem and the file and line number of where the problem occurred:</p>
<p><code><br />
[Tue May 26 19:54:53 2009] [error] [client 127.0.0.1] PHP Fatal error:  Call to undefined function doesNotExist() in /var/www/index.php on line 6<br />
</code></p>
<p>I&#8217;ve written a small bash script to mail me all of the PHP errors that it finds in the log. The results are sorted and piped through the &#8220;uniq&#8221; command to remove any duplicate errors. I&#8217;ve set it up to run as a cron task once a day, so if there are ever any problems it isn&#8217;t long before I know about them. The code is below:</p>
<pre name="code" class="python">
#!/bin/bash
# Mail out PHP errors that are in the apache error log.
# Note PHP's log_errors must be turned on
# Ben Dowling - www.coderholic.com

errorLog=/var/log/apache2/error.log # Error log location
email=you-email-address@example.com # Send report here

# Pull out the lines that mention PHP, and use AWK to get the column we're interested in
errors=$(cat $errorLog | grep PHP | awk -F'] ' '{print $4}')
# Remove referer information, sort, and remove duplicate entries
errors=$(echo "$errors" | awk -F', referer' '{print $1}' | sort | uniq)
# Check that we actually have some errors
if [ -n "$errors" ]
then
	echo "$errors" | mail "$email" -s "PHP Errors"
fi
</pre>
<p>If you need to it should be quite easy to modify the script for a slightly different use, such as printing out all the fatal PHP errors that are in the log. </p>
<p>Hope you find it useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/php-error-log-mailscript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Ultimate Scalability Presentation</title>
		<link>http://www.coderholic.com/the-ultimate-scalability-presentation/</link>
		<comments>http://www.coderholic.com/the-ultimate-scalability-presentation/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 19:37:54 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[software design]]></category>
		<category><![CDATA[web dev]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=231</guid>
		<description><![CDATA[At work we&#8217;re experiencing some fairly rapid growth, and our single production server is starting the feel the strain. I&#8217;ve been doing a lot of investigation into how we can scale the site, and thankfully there is lots of information out there. The &#8220;Do you Scale&#8221; presentation I saw at PHP London a couple of [...]]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://www.mendeley.com">work</a> we&#8217;re experiencing some fairly rapid growth, and our single production server is starting the feel the strain. I&#8217;ve been doing a lot of investigation into how we can scale the site, and thankfully there is lots of information out there. </p>
<p>The &#8220;<a href="http://www.coderholic.com/php-london/">Do you  Scale</a>&#8221; presentation I saw at PHP London a couple of months ago gave a good high level overview of scalability issues, and included some useful techniques to help you scale.</p>
<p>I think I&#8217;ve found the ultimate scalability presentation though: &#8220;Real World Web: Performance &#038; Scalability&#8221;. The 189 slides contained within this presentation cover almost everything I&#8217;ve read elsewhere, and it&#8217;s packed full of practice advice!</p>
<p><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rwwmysql2008-1216304757388368-8&#038;stripped_title=real-world-web-performance-scalability" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rwwmysql2008-1216304757388368-8&#038;stripped_title=real-world-web-performance-scalability" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/the-ultimate-scalability-presentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript, JSON and PHP</title>
		<link>http://www.coderholic.com/javascript-json-and-php/</link>
		<comments>http://www.coderholic.com/javascript-json-and-php/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 14:11:10 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=205</guid>
		<description><![CDATA[JSON data is commonly used as a simple way to send data back to client side javascript from the server. For example, a PHP script may output the following JSON to confirm that an action was taken: {success: true, message: "It worked!"} or in the case of failure: {success: fase, message: "It didn't work!"} Below [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/JSON">JSON</a> data is commonly used as a simple way to send data back to client side javascript from the server. For example, a PHP script may output the following JSON to confirm that an action was taken:</p>
<pre name="code" class="javascript">
{success: true, message: "It worked!"}
</pre>
<p>or in the case of failure:</p>
<pre name="code" class="javascript">
{success: fase, message: "It didn't work!"}
</pre>
<p>Below is a basic javascript callback function to process the JSON data, displaying the returned message:</p>
<pre name="code" class="javascript">
function callback(data) {
    if(data.success) alert(data.message);
    else alert('ERROR:' + data.message);
}
</pre>
<p>Sometimes it&#8217;s actually useful to send back javascript code to in the JSON data, to be run on the client. For example, if an Ajax request is made that updates some account information we could return javascript code to update several parts of the page with the new information. Here&#8217;s PHP code that outputs JSON data which includes javascript code:</p>
<pre name="code" class="php">
$response = array('success' => 'true',
    'code' => "jQuery('#id').html('Success!');");
echo json_encode($response);
// Outputs {success: true, code: "jQuery('#id').html('Success!');"}
</pre>
<p>Note how in the returned JSON data &#8220;code&#8221; is actually a string, so it won&#8217;t be possible to run the code simply by doing &#8220;data.code()&#8221; on the client. Instead we must explicitly tell javascript to evaluate the string as code. Below is an example of how we can do this using <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/eval">eval</a>:</p>
<pre name="code" class="javascript">
function callback(data) {
    if(data.success &#038;&#038; data.code) eval(data.code);
}
</pre>
<p>If we wanted to update the page with HTML more complicate the the simple &#8220;Success!&#8221; message in the previous example we must be careful to escape any quotes in the HTML correctly. If we wanted to set the content to: &#8220;Javascript&#8221;, &#8220;json&#8221;, &#8220;PHP&#8221; then we&#8217;d need to do the following:</p>
<pre name="code" class="php">
$response = array('success' => 'true',
    'code' => "jQuery('#id').html('\"Javascript\", \"json\", \"PHP"');");
echo json_encode($response);
</pre>
<p>And It&#8217;s easy to imagine a far more complicated example. The code becomes less readable, and if you accidentally forget to escape one of the quotes, or escape of the quotes that shouldn&#8217;t be escaped, then the whole thing breaks.  A nice alternative is ty store the HTML as a separate JSON property and then to reference it, avoiding the need to escape the quotes and making the code easier to read:</p>
<pre name="code" class="php">
$response = array('success' => 'true',
    'html' => '"Javascript", "json", "PHP"',
    'code' => "jQuery('#id').html(this.html);");
echo json_encode($response);
</pre>
<p>However, to make the &#8220;this.html&#8221; reference work the clients side callback function will need to changed, as eval() runs the code in global scope. This means that &#8220;this.html&#8221; will refer to a global html variable rather than the one in our JSON data. We can get around this problem by using the <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function/apply">apply</a> function as follows:</p>
<pre name="code" class="javascript">
function callback(data) {
    if(data.success &#038;&#038; data.code) {
        var f = new Function(data.code);
        f.apply(data);
    }
}
</pre>
<p>And here&#8217;s a complete example which uses jQuery to perform the Ajax call:</p>
<pre name="code" class="javascript">
jQuery.get('update.php', {} function(data) {
    if(data.success &#038;&#038; data.code) {
        var f = new Function(data.code);
        f.apply(data);
    }, 'json');
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/javascript-json-and-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP London</title>
		<link>http://www.coderholic.com/php-london/</link>
		<comments>http://www.coderholic.com/php-london/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 19:53:05 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=175</guid>
		<description><![CDATA[Ever since moving to London last August I&#8217;ve been meaning to attend some of the many technology based meetup groups. Last Thursday I finally got round to it, and attended PHP London. Andrew Betts gave a great talk on scaling web applications, entitled &#8220;Do You Scale?&#8221;. The slides are below: Do You Scale View more [...]]]></description>
			<content:encoded><![CDATA[<p>Ever since moving to London last August I&#8217;ve been meaning to attend some of the many <a href="http://www.meetup.com/cities/gb/london/groups/technology/?radius=25.0">technology based meetup groups</a>. Last Thursday I finally got round to it, and attended <a href="http://www.phplondon.org/">PHP London</a>.</p>
<p>Andrew Betts gave a great talk on scaling web applications, entitled &#8220;Do You Scale?&#8221;. The slides are below:</p>
<div style="width:425px;text-align:left" id="__ss_1109560"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/triblondon/do-you-scale?type=presentation" title="Do You Scale">Do You Scale</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=doyouscale-090306032757-phpapp02&#038;stripped_title=do-you-scale" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=doyouscale-090306032757-phpapp02&#038;stripped_title=do-you-scale" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/triblondon">triblondon</a>. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/caching">caching</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/sessions">sessions</a>)</div>
</div>
<p>I&#8217;ll certainly be going back to PHP London next month. I&#8217;m also going to make more of an effort to attend some of the other meetups, which will hopefully be as informative and enjoyable as this one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/php-london/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Database Query Logging with PDO</title>
		<link>http://www.coderholic.com/php-database-query-logging-with-pdo/</link>
		<comments>http://www.coderholic.com/php-database-query-logging-with-pdo/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 22:47:38 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[web dev]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=164</guid>
		<description><![CDATA[One thing I really like about CakePHP is that when it&#8217;s in debug mode it prints out a list of all the database queries used to generate a page, along with the time it took to run each query. This makes it really easy to find problem queries that are slowing down your site. It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>One thing I really like about <a href="http://cakephp.org/">CakePHP</a> is that when it&#8217;s in debug mode it prints out a list of all the database queries used to generate a page, along with the time it took to run each query. This makes it really easy to find problem queries that are slowing down your site. It&#8217;s such a great feature that I wanted something similar for projects that don&#8217;t use CakePHP. </p>
<p>What I came up with was a LoggedPDO class that extends PHP&#8217;s <a href="http://uk.php.net/pdo">PDO</a> class. If you&#8217;re already using PDO in your project you only need to change a single line of code to enable database query logging:</p>
<pre name="code" class="php">
// Standard PDO...
$db = new PDO($dsn, $username, $password);
// ...should be changed to
$db = new LoggedPDO($dsn, $username, $password);
</pre>
<p>And then all your database queries will be logged, timed and all information printed out at the end of each page. My code also includes a decorator for PDOStatements so any prepared statements that get executed also get logged. Below is a small sample of the code in use:</p>
<pre name="code" class="php">
$db = new LoggedPDO("mysql:dbname=test;host=localhost", "root");
$results = $db-&gt;query("SHOW TABLES");
$tables = $results-&gt;fetchAll(PDO::FETCH_COLUMN);
foreach($tables AS $table) {
	$statement = $db-&gt;prepare("DESCRIBE :table");
	$statement-&gt;bindParam(":table", $table, PDO::PARAM_STR);
	$results = $statement-&gt;execute();
	$columns = $statement-&gt;fetchAll(PDO::FETCH_ASSOC);
}
</pre>
<p>Which would output:</p>
<table border=1>
<tr>
<th>Query</th>
<th>Time (ms)</th>
</tr>
<tr>
<td>SHOW TABLES</td>
<td>0.174</td>
</tr>
<tr>
<td>[PS] DESCRIBE :table</td>
<td>0.06</td>
</tr>
<tr>
<td>[PS] DESCRIBE :table</td>
<td>0.032</td>
</tr>
<tr>
<th>3 queries</th>
<th>0.266</th>
</tr>
</table>
<p>Full code for the both the LoggedPDO and LoggedPDOStatement classes is below:</p>
<pre name="code" class="php">
/**
* Extends PDO and logs all queries that are executed and how long
* they take, including queries issued via prepared statements
*/
class LoggedPDO extends PDO
{
	public static $log = array();

	public function __construct($dsn, $username = null, $password = null) {
		parent::__construct($dsn, $username, $password);
	}

	/**
	 * Print out the log when we're destructed. I'm assuming this will
	 * be at the end of the page. If not you might want to remove this
	 * destructor and manually call LoggedPDO::printLog();
	 */
	public function __destruct() {
		self::printLog();
	}

	public function query($query) {
		$start = microtime(true);
		$result = parent::query($query);
		$time = microtime(true) - $start;
		LoggedPDO::$log[] = array('query' =&gt; $query,
				                  'time' =&gt; round($time * 1000, 3));
		return $result;
	}

	/**
	 * @return LoggedPDOStatement
	 */
	public function prepare($query) {
		return new LoggedPDOStatement(parent::prepare($query));
	}

	public static function printLog() {
		$totalTime = 0;
		echo '&lt;table border=1&gt;&lt;tr&gt;&lt;th&gt;Query&lt;/th&gt;&lt;th&gt;Time (ms)&lt;/th&gt;&lt;/tr&gt;';
		foreach(self::$log as $entry) {
			$totalTime += $entry['time'];
			echo '&lt;tr&gt;&lt;td&gt;' . $entry['query'] . '&lt;/td&gt;&lt;td&gt;' . $entry['time'] . '&lt;/td&gt;&lt;/tr&gt;\n';
		}
		echo '&lt;tr&gt;&lt;th&gt;' . count(self::$log) . ' queries&lt;/th&gt;&lt;th&gt;' . $totalTime . '&lt;/th&gt;&lt;/tr&gt;\n';
		echo '&lt;/table&gt;';
	}
}

/**
* PDOStatement decorator that logs when a PDOStatement is
* executed, and the time it took to run
* @see LoggedPDO
*/
class LoggedPDOStatement {
	/**
	 * The PDOStatement we decorate
	 */
	private $statement;

	public function __construct(PDOStatement $statement) {
		$this-&gt;statement = $statement;
	}

	/**
	* When execute is called record the time it takes and
	* then log the query
	* @return PDO result set
	*/
	public function execute() {
		$start = microtime(true);
		$result = $this-&gt;statement-&gt;execute();
		$time = microtime(true) - $start;
		LoggedPDO::$log[] = array('query' =&gt; '[PS] ' . $this-&gt;statement-&gt;queryString,
				                  'time' =&gt; round($time * 1000, 3));
		return $result;
	}
	/**
	* Other than execute pass all other calls to the PDOStatement object
	* @param string $function_name
	* @param array $parameters arguments
	*/
	public function __call($function_name, $parameters) {
		return call_user_func_array(array($this-&gt;statement, $function_name), $parameters);
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/php-database-query-logging-with-pdo/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Beware PHP&#8217;s split()</title>
		<link>http://www.coderholic.com/beware-phps-split/</link>
		<comments>http://www.coderholic.com/beware-phps-split/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 22:40:11 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=140</guid>
		<description><![CDATA[Many programming languages have have a join function that takes an array of strings and concatenates them, and a corresponding split function that does the opposite: takes a string and splits it up into an array. Python has join and split, C# has join and split, Javascript has join and split, and Java has a [...]]]></description>
			<content:encoded><![CDATA[<p>Many programming languages have have a join function that takes an array of strings and concatenates them, and a corresponding split function that does the opposite: takes a string and splits it up into an array.</p>
<p>Python has join and split, C# has join and split, Javascript has join and split, and Java has a split (although it&#8217;s sadly missing a join). PHP, though, has implode and explode. They do the same thing as join and split in other languages, it&#8217;s just that PHP has decided not to to follow the standard naming convention for these functions.</p>
<p>Fortunately for developers like me who are used to the &#8220;join&#8221; and &#8220;split&#8221; names PHP has aliases. Therefore you can happily call join and split in PHP and it&#8217;ll basically call implode and explode for you&#8230; or so I though! Unfortunately this isn&#8217;t the case! Join is an alias of implode. From the <a href="http://uk2.php.net/join">PHP documentation</a>:</p>
<blockquote><p>join — Alias of implode()</p></blockquote>
<p>And here&#8217;s the <a href="http://uk2.php.net/implode">documentation for implode</a>:</p>
<blockquote><p>
implode — Join array elements with a string<br />
string implode  ( string $glue  , array $pieces  )
</p></blockquote>
<p>That&#8217;s pretty clear. It&#8217;s not quite the case for <a href="http://uk2.php.net/split">split</a> though:</p>
<blockquote><p>
split — Split string into array by regular expression<br />
array split  ( string $pattern  , string $string  [, int $limit  ] )
</p></blockquote>
<p>Notice how it isn&#8217;t defined as an alias of explode! Here&#8217;s the <a href="http://uk2.php.net/explode">documentation for explode</a>:</p>
<blockquote><p>
explode — Split a string by string<br />
array explode  ( string $delimiter  , string $string  [, int $limit=-1  ] )
</p></blockquote>
<p>Notice how it&#8217;s ever so slightly different? The explode function takes a string delimiter, but split takes a regular expression string! This means that in the majority of cases you&#8217;ll get exactly the same result from both functions, but you&#8217;ll suffer a slight performance hit with split. Using my <a href="http://www.coderholic.com/php-profile-class/">profile class</a> I worked out that explode is just over twice as fast as split.</p>
<p>The real problem arises when your delimiter string contains characters that mean something different when interpreted as a regular expression (such as &#8220;.&#8221;, &#8220;|&#8221;, &#8220;?&#8221;, &#8220;+&#8221; and &#8220;*&#8221;). See the following example with a &#8220;.&#8221;:</p>
<pre name="code" class="php">
&lt;?php
$sentence = "One. Two.";
var_dump(split(".", $sentence));
/* Output:
array(10) {
  [0]=&gt;
  string(0) ""
  [1]=&gt;
  string(0) ""
  [2]=&gt;
  string(0) ""
  [3]=&gt;
  string(0) ""
  [4]=&gt;
  string(0) ""
  [5]=&gt;
  string(0) ""
  [6]=&gt;
  string(0) ""
  [7]=&gt;
  string(0) ""
  [8]=&gt;
  string(0) ""
  [9]=&gt;
  string(0) ""
} */
var_dump(explode(".", $sentence));
/* Output:
array(3) {
  [0]=&gt;
  string(3) "One"
  [1]=&gt;
  string(4) " Two"
  [2]=&gt;
  string(0) ""
} */
?&gt;
</pre>
<p>So you&#8217;ve been warned! Feel free to use join instead of implode, but use split with caution!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/beware-phps-split/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Handling Contact Form Failure</title>
		<link>http://www.coderholic.com/handling-contact-form-failure/</link>
		<comments>http://www.coderholic.com/handling-contact-form-failure/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 15:53:40 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[web dev]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=104</guid>
		<description><![CDATA[There is an article over a DZone today &#8220;What if your contact form fails?&#8221;. The article discusses what to do if the contact form on your website fails to send a message. The approach they suggest is to display a message to the user saying it failed, and presenting them with a mailto link so [...]]]></description>
			<content:encoded><![CDATA[<p>There is an article over a DZone today <a href="http://css.dzone.com/news/what-if-your-contact-form-fail">&#8220;What if your contact form fails?&#8221;</a>. The article discusses what to do if the contact form on your website fails to send a message. The approach they suggest is to display a message to the user saying it failed, and presenting them with a mailto link so they can send you an email themselves.</p>
<p>This is one approach to the failed contact form problem, but it isn&#8217;t going to help much if the problem is actually with your email address. For example, you may have exceeded your disk quota, or you might have a badly configured mail server. </p>
<p>Another problem with the mail solution is that it requires the user to perform another action. They&#8217;ve gone to the trouble of filling out a contact form. If that fails they might not bother to send to send you an email too (although the suggested approach in the article does reduce the effort required).</p>
<p><strong>An Alternative Approach</strong></p>
<p>So what other approaches are there? What I do is store all contact form information in a database. Below is the SQL to create the basic messages table:</p>
<pre name="code" class="sql">
CREATE TABLE messages (
    id int auto_increment NOT NULL,
    sent timestamp NOT NULL,
    sender varchar(255) NOT NULL,
    message text,

    PRIMARY KEY(id)
);
</pre>
<p>Then when a contact form gets submitted you can store the information in the database before sending an email. Below is some sample PHP code, using PDO to access the database:</p>
<pre name="code" class="php">
// Get the form data
$sender = $_POST['sender'];
$message = $_POST['message'];

// Add the message to the database
$query = "INSERT INTO messages(sender, message) VALUES (:sender, :message);
$stmt = $pdo->prepare($query);
$stmt->bindParam(':sender', $sender, PDO::PARAM_STR);
$stmt->bindParam(':message', $message, PDO::PARAM_STR);
$stmt->execute();

// Send the mail
mail("me@my.domain", "Contact Form Message", $message, "From: {$sender}");
</pre>
<p>All that is left to do is create an admin page that lists all messages, and allows us to delete them. We could even include a link to the admin page in the emails we send to ourselves. By using this approach we never lose the message content, even if the mail call fails, because they all get stored in the database. All we need to do is check the admin page every so often and we&#8217;ll soon see if there are any new messages there.</p>
<p>Of course, this approach doesn&#8217;t have to be used in isolation. We can combine it with the approach suggested in the DZone article, and present the user with a mail link if sending the mail does fail. If the user decides not to send a mail though, we haven&#8217;t lost anything.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/handling-contact-form-failure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Profile Class</title>
		<link>http://www.coderholic.com/php-profile-class/</link>
		<comments>http://www.coderholic.com/php-profile-class/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 18:38:55 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=89</guid>
		<description><![CDATA[Profiling is a important part of software development, allowing you to find bottlenecks in your application and discover areas that would benefit from optimisation. In PHP a common technique is to calculate the total time to render a page. This can be achieved using the microtime function: &#60;?php $startTime = microtime(true); // normal page code [...]]]></description>
			<content:encoded><![CDATA[<p>Profiling is a important part of software development, allowing you to find bottlenecks in your application and discover areas that would benefit from optimisation. In PHP a common technique is to calculate the total time to render a page. This can be achieved using the <a href="http://uk.php.net/microtime">microtime</a> function:</p>
<pre class="php" name="code">&lt;?php
$startTime = microtime(true);

// normal page code here

$time = microtime(true) - $startTime;
echo "&lt;!-- Page generation time: {$time} seconds --&gt;";
?&gt;</pre>
<p>This simple approach is a a great way to find out how long certain pages are taking to load. Sometimes, however, you want more granular profiling information. That&#8217;s why I created a Profile class, which records the execution time of a given method. Here&#8217;s how to use it:</p>
<pre class="php" name="code">
$p = new Profile();
$time = $p->profile("myClassName", "methodName", array("arg1", "arg2"));
</pre>
<p>You can also pass in an optional fourth argument, which specifies how many times to run the given method. After running it multiple times you can call the <code>Profile::printDetails()</code> method to view the total time, average invocation time, and the maximum single invocation time. Below is a simple example:</p>
<pre class="php" name="code">
&lt;?php
include("Profile.php");

/**
 * Test class just for the purposes of demonstration
 */
class Test {
	public function add($a, $b) {
		// add the numbers together 100 times
		for($i = 0; $i < 100; $i++) {
			$c = $a + $b;
		}
	}
}

$p = new Profile();
$p->profile("Test", "add", array(1, 2), 1000);
$p->printDetails();
?&gt;
</pre>
<p>If you run the above code you&#8217;ll see the following output:</p>
<blockquote><p>
Test::add(1, 2) was invoked 1000 times<br />
Total duration:   0.0447s<br />
Average duration: 0s<br />
Worst duration:   0.002s
</p></blockquote>
<p>The code listing for the Profile class is below, with some of the comments removed for the sake of brevity. A fully commented version is available for <a href='http://www.coderholic.com/wp-content/uploads/2008/09/profile.zip'>download</a>.</p>
<pre class="php" name="code">
&lt;?php
/**
 * Class to time the execution of method calls.
 *
 * @author Ben Dowling - www.coderholic.com
 */
class Profile {
	/**
	 * Stores details about the last profiled method
	 */
	private $details;

    public function __construct() {}

	/**
	 * @param classname string
	 * @param methodname string
	 * @param methodargs array
	 * @param invocations int The number of times to call the method
	 * @return float average invocation duration in seconds
	 */
	public function profile($classname, $methodname, $methodargs, $invocations = 1) {
		if(class_exists($classname) != TRUE) {
			throw new Exception("{$classname} doesn't exist");
		}

		$method = new ReflectionMethod($classname, $methodname);

		$instance = NULL;
		if(!$method-&gt;isStatic()) 		{
			$class = new ReflectionClass($classname);
			$instance = $class-&gt;newInstance();
		}

		$durations = array();
		for($i = 0; $i &lt; $invocations; $i++) {
			$start = microtime(true);
			$method-&gt;invokeArgs($instance, $methodargs);
			$durations[] = microtime(true) - $start;
		}

		$duration["total"] = round(array_sum($durations), 4);
		$duration["average"] = round($duration["total"] / count($durations), 4);
		$duration["worst"] = round(max($durations), 4);	

		$this-&gt;details = array(	"class" =&gt; $classname,
							   	"method" =&gt; $methodname,
							   	"arguments" =&gt; $methodargs,
						 		"duration" =&gt; $duration,
								"invocations" =&gt; $invocations);

		return $duration["average"];
	}

	/**
	 * @return string
	 */
	private function invokedMethod() {
		return "{$this-&gt;details["class"]}::{$this-&gt;details["method"]}(" .
			 join(", ", $this-&gt;details["arguments"]) . ")";
	}

	/**
	 * Prints out details about the last profiled method
	 */
	public function printDetails() {
		$methodString = $this-&gt;invokedMethod();
		$numInvoked = $this-&gt;details["invocations"];

		if($numInvoked == 1) {
			echo "{$methodString} took {$this-&gt;details["duration"]["average"]}s\n";
		}

		else {
			echo "{$methodString} was invoked {$numInvoked} times\n";
			echo "Total duration:   {$this-&gt;details["duration"]["total"]}s\n";
			echo "Average duration: {$this-&gt;details["duration"]["average"]}s\n";
			echo "Worst duration:   {$this-&gt;details["duration"]["worst"]}s\n";
		}
	}
}

?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/php-profile-class/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
