<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>Derick Rethans - tag: blog</title>
    <link>http://derickrethans.nl/feed-blog.xml</link>
    <description>This feed shows the latest 15 items with the tag blog</description>
    <language>en-us</language>
    <copyright>All rights reserved - Derick Rethans</copyright>
    <managingEditor>derick@derickrethans.nl (Derick Rethans)</managingEditor>
    <pubDate>Tue, 22 May 2012 22:57:05 +0000</pubDate>
    <lastBuildDate>Tue, 22 May 2012 22:57:05 +0000</lastBuildDate>
    <generator>eZ Components Feed dev (http://ezcomponents.org/docs/tutorials/Feed)</generator>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <ttl>60</ttl>
    <item>
      <title>MongoDB Cursors with PHP</title>
      <link>http://derickrethans.nl/cursors-in-mongodb.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="mongodb_cursors_with_php"/&gt;MongoDB Cursors with PHP&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Tuesday, May 22nd 2012, 09:15 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Recently I was asked to improve the &lt;a href="http://docs.php.net/manual/en/mongocursor.batchsize.php"&gt;MongoCursor::batchSize&lt;/a&gt; documentation. This began an indepth investigation in how the PHP &lt;a href="http://php.net/mongodb"&gt;driver&lt;/a&gt; for &lt;a href="http://mongodb.org"&gt;MongoDB&lt;/a&gt; handles pulling data that's been queried from the MongoDB server. Here are my findings.&lt;/p&gt;
      &lt;p&gt;A &lt;a href="http://docs.php.net/manual/en/mongocursor.php"&gt;MongoCursor&lt;/a&gt; is created as soon as you run the &lt;a href="http://docs.php.net/manual/en/mongocursor.find.php"&gt;find()&lt;/a&gt; method on a &lt;a href="http://docs.php.net/manual/en/mongocollection.php"&gt;MongoCollection&lt;/a&gt; object, like in:&lt;/p&gt;
      &lt;pre&gt;$m = new Mongo();
$collection = $m-&gt;demoDb-&gt;demoCollection;
$cursor = $collection-&gt;find();

&lt;/pre&gt;
      &lt;img src="http://derickrethans.nl/images/content/cursor.gif" class="right" alt="cursor.gif"/&gt;
      &lt;p&gt;Just calling &lt;code&gt;find()&lt;/code&gt; will only create a cursor object, and does not immediately send the query to the server for processing. That is only done as soon as you start reading from the cursor for the first time. Because of this, you can call additional methods on the newly created cursor object that still influence how the query is run on the server. One of such examples is the &lt;a href="http://docs.php.net/manual/en/mongocursor.sort.php"&gt;sort()&lt;/a&gt; method that makes the result sort according to its arguments (in this example, by name):&lt;/p&gt;
      &lt;pre&gt;$cursor-&gt;sort( array( 'name' =&gt; 1 ) );
$result = $cursor-&gt;getNext();

&lt;/pre&gt;
      &lt;p&gt;When you then call &lt;a href="http://docs.php.net/manual/en/mongocursor.getnext.php"&gt;getNext()&lt;/a&gt; on &lt;code&gt;$cursor&lt;/code&gt; the driver sends to the server the query, and requests to return a default number of documents in the first batch. The default &lt;em&gt;Batch Size&lt;/em&gt; is 101. Let's have a look on what's get send on the wire in our simple query for all documents, sorted by name:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/01-find-sort-name.jpg" alt="01-find-sort-name.jpg"/&gt;
      &lt;p&gt;The &lt;em&gt;Number to Return&lt;/em&gt; is 0, which means to use the default. So even although we only want to fetch one result (&lt;code&gt;getNext()&lt;/code&gt; asks the cursor for the next document &lt;strong&gt;only&lt;/strong&gt;), the server returns 101 documents:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/02-find-sort-name.jpg" alt="02-find-sort-name.jpg"/&gt;
      &lt;p&gt;The driver stores all 101 documents locally and during the next 100 calls to &lt;code&gt;getNext()&lt;/code&gt; the driver will simply return the documents from the local memory. Once &lt;code&gt;getNext()&lt;/code&gt; gets called for the 102th time, the driver connects back to the server to request more documents:&lt;/p&gt;
      &lt;pre&gt;// skip the other 100 docs
for ($i = 0; $i &lt; 100; $i++) { $cursor-&gt;getNext(); }
// request document 102:
$result = $cursor-&gt;getNext();

&lt;/pre&gt;
      &lt;p&gt;When the driver asks for more documents separately (i.e., not at the same time it is issuing a query) without a specific batch size, the server fills up 4MB of documents. On the wire, the request for &lt;em&gt;Get More&lt;/em&gt; looks like:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/03-find-sort-name.jpg" alt="03-find-sort-name.jpg"/&gt;
      &lt;p&gt;and the reply like:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/04-find-sort-name.jpg" alt="04-find-sort-name.jpg"/&gt;
      &lt;p&gt;As you can see, the returned data is &lt;code&gt;4194378&lt;/code&gt; bytes, and the &lt;em&gt;Number Returned&lt;/em&gt; is &lt;code&gt;34673&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Setting your own batch size&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;You can instruct the driver to use different batch sizes, by using the &lt;a href="http://docs.php.net/manual/en/mongocursor.batchsize.php"&gt;batchSize()&lt;/a&gt; method on the &lt;code&gt;$cursor&lt;/code&gt;. In this new example, we use the &lt;code&gt;batchSize()&lt;/code&gt; method to request &lt;code&gt;25&lt;/code&gt; documents per round trip to the server:&lt;/p&gt;
      &lt;pre&gt;$cursor = $collection-&gt;find()-&gt;sort( array( 'name' =&gt; 1 ) );
$cursor-&gt;batchSize(25);
$result = $cursor-&gt;getNext();

&lt;/pre&gt;
      &lt;p&gt;When we run this script, we will see the following on the wire:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/05-batch25.jpg" alt="05-batch25.jpg"/&gt;
      &lt;p&gt;As expected, the &lt;em&gt;Number to Return&lt;/em&gt; is now 25. During iteration, all query results are returned from the server to the driver in batches of 25 documents:&lt;/p&gt;
      &lt;pre&gt;// retrieve another 25 documents to trigger the getMore
for ($i = 0; $i &lt; 25; $i++) { $cursor-&gt;getNext(); }

&lt;/pre&gt;
      &lt;p&gt;Which creates this query:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/06-batch25.jpg" alt="06-batch25.jpg"/&gt;
      &lt;p&gt;And this reply:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/07-batch25.jpg" alt="07-batch25.jpg"/&gt;
      &lt;p&gt;As you can see, another 25 documents are returned, starting from the 25th document.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Using limit&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;Besides &lt;code&gt;batchSize()&lt;/code&gt;, the driver also supports &lt;a href="http://docs.php.net/manual/en/mongocursor.limit.php"&gt;limit()&lt;/a&gt;. &lt;code&gt;limit()&lt;/code&gt; is something that exclusively happens on the client side. It is just a counter that restricts how often the cursor can iterate over the data. However, the driver also uses the value passed to the function to ask for only the amount of documents that it still needs to fetch. This means that if we run this script, the driver will request 50000 documents:&lt;/p&gt;
      &lt;pre&gt;$cursor = $c-&gt;find()-&gt;sort( array( 'name' =&gt; 1 ) );
$cursor-&gt;limit( 50000 );
$res = $cursor-&gt;getNext();

&lt;/pre&gt;
      &lt;p&gt;On the wire we'll see:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/09-limit50000.jpg" alt="09-limit50000.jpg"/&gt;
      &lt;p&gt;Sadly, not all 50000 documents fit in the first reply (as every reply is limited to 4MB) and the server replies that it has only returned &lt;code&gt;34678&lt;/code&gt; documents:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/10-limit50000.jpg" alt="10-limit50000.jpg"/&gt;
      &lt;p&gt;The driver now calculates how many documents it still needs to fullfill it's limit of 50000: &lt;code&gt;50000 - 34678 = 15322&lt;/code&gt;. It then requests those images with a &lt;em&gt;Get More&lt;/em&gt; query:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/11-limit50000.jpg" alt="11-limit50000.jpg"/&gt;
      &lt;p&gt;It is also possible to combine &lt;code&gt;limit()&lt;/code&gt; and &lt;code&gt;batchSize()&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Combining limit and batchSize&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;If we just use &lt;code&gt;limit()&lt;/code&gt; then the driver will always try to fetch as many documents it can to full-fill the limit. This sometimes means it will fill up all 4MB of the maximum allowed reply packet, especially if your limit is set high enough (in our example, that's more than &lt;code&gt;34678&lt;/code&gt; documents). That's not often what you want, and you can use a combination of &lt;code&gt;limit()&lt;/code&gt; and &lt;code&gt;batchSize()&lt;/code&gt; to fix it. If we want to query at most 128 documents with at most 50 documents per batch, we can specify that as:&lt;/p&gt;
      &lt;pre&gt;$cursor = $c-&gt;find()-&gt;sort( array( 'name' =&gt; 1 ) );
$cursor-&gt;limit( 128 )-&gt;batchSize( 50 );
$res = $cursor-&gt;getNext();
// retrieve the other 127 documents that we still want
for ($i = 0; $i &lt; 127; $i++) { $cursor-&gt;getNext(); }

&lt;/pre&gt;
      &lt;p&gt;On the wire, we'll see the following exchange:&lt;/p&gt;
      &lt;p&gt;Initial query:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/12-limitbatch.jpg" alt="12-limitbatch.jpg"/&gt;
      &lt;p&gt;First 50 documents:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/13-limitbatch.jpg" alt="13-limitbatch.jpg"/&gt;
      &lt;p&gt;First &lt;em&gt;Get More&lt;/em&gt; for the second batch of 50:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/14-limitbatch.jpg" alt="14-limitbatch.jpg"/&gt;
      &lt;p&gt;The second batch of 50 documents:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/15-limitbatch.jpg" alt="15-limitbatch.jpg"/&gt;
      &lt;p&gt;The second and last &lt;em&gt;Get More&lt;/em&gt; for a batch of 28 (&lt;code&gt;128 - 50 - 50 = 28&lt;/code&gt;):&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/16-limitbatch.jpg" alt="16-limitbatch.jpg"/&gt;
      &lt;p&gt;And the last batch of 28 documents returned:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/17-limitbatch.jpg" alt="17-limitbatch.jpg"/&gt;
      &lt;p&gt;I wouldn't quite suggest you use a small batch such as 50 though as it would incur lots of round trips from and to the server. In some cases a small batch size makes sense.&lt;/p&gt;
      &lt;p&gt;Take for example a situation where you need to process 100.000s of documents and the processing time for each item is 2 seconds. In the first batch, the driver will pull 101 documents, which in total will take 202 seconds. When the driver attempts to fetch the next batch with &lt;em&gt;Get More&lt;/em&gt;, it fails because the default cursor time-out (on the client size) is only 30 seconds. Setting your batch size to 5 in this case avoids your cursor from timing out. You can of course also &lt;a href="http://php.net/manual/en/mongocursor.timeout.php"&gt;change the cursor timeout&lt;/a&gt;. Do not use the &lt;a href="http://www.php.net/manual/en/mongocursor.immortal.php"&gt;immortal&lt;/a&gt; flag though, as that means something else (see &lt;em&gt;NoCursorTimeout&lt;/em&gt; at the &lt;a href="http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol#MongoWireProtocol-OPQUERY"&gt;MongoDB Wire Protocol&lt;/a&gt; documentation).&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;One More Thing&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;Setting the batch size to 1, as well as setting a negative batch size has a special meaning for the MongoDB server. In both cases, it instructs the server to return up to the absolute value of the requested and then terminate the cursor, allowing no further documents to be fetched. That means that this script doesn't do what you expect it to:&lt;/p&gt;
      &lt;pre&gt;$cursor = $c-&gt;find()-&gt;sort( array( 'name' =&gt; 1 ) );
$cursor-&gt;batchSize( 1 )-&gt;limit( 10 );
$cursor-&gt;getNext();
var_dump( $cursor-&gt;getNext() );

&lt;/pre&gt;
      &lt;p&gt;The &lt;code&gt;var_dump()&lt;/code&gt; for the second &lt;code&gt;getNext()&lt;/code&gt; will always return &lt;code&gt;NULL&lt;/code&gt;. However, if you set a batch size of 2, it works just like you would expect:&lt;/p&gt;
      &lt;pre&gt;$cursor = $c-&gt;find()-&gt;sort( array( 'name' =&gt; 1 ) );
$cursor-&gt;batchSize( 2 )-&gt;limit( 10 );
$cursor-&gt;getNext(); // item 1
$cursor-&gt;getNext(); // item 2
var_dump( $cursor-&gt;getNext() ); // item 3

&lt;/pre&gt;
      &lt;p&gt;Now let's set a batch size of &lt;code&gt;-2&lt;/code&gt; and see what happens on the wire. The request is:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/18-neg-batch.jpg" alt="18-neg-batch.jpg"/&gt;
      &lt;p&gt;As you can see, the driver really sends &lt;code&gt;-2&lt;/code&gt; to the server, indicating that negative batch sizes are handled on the server side.&lt;/p&gt;
      &lt;p&gt;And the reply is:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/19-neg-batch.jpg" alt="19-neg-batch.jpg"/&gt;
      &lt;p&gt;The &lt;em&gt;Cursor ID&lt;/em&gt; is &lt;code&gt;0&lt;/code&gt; in the reply, meaning that there is no cursor to fetch further documents.&lt;/p&gt;
      &lt;p&gt;We have now come to the end of the article on MongoDB's cursors. All the screenshots of the packets on the wire were made with WireShark, which has support for the MongoDB wire protocol. You can read more about the wire protocol at &lt;a href="http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol;"&gt;http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol;&lt;/a&gt; but this is often not something you should have to be concerned about. Just to sum things up:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;p&gt;the &lt;strong&gt;Batch Size&lt;/strong&gt; controls how many documents the server sends in a reply packet.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;the server will never send more documents than fit in 4MB.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;the &lt;strong&gt;Limit&lt;/strong&gt; option controls how many documents the driver will (try to) fetch from the server.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;by default the first batch of documents without any limits specified is 101 documents.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;a negative &lt;strong&gt;Batch Size&lt;/strong&gt; or a Batch Size of 1, will terminate the cursor immediately after returning the next batch of documents.&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201205220915</guid>
      <pubDate>Tue, 22 May 2012 08:15:00 +0000</pubDate>
    </item>
    <item>
      <title>Ignite London: Crowd Sourcing a Map of the World</title>
      <link>http://derickrethans.nl/ignite-openstreetmap.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="ignite_london_crowd_sourcing_a_map_of_the_world"/&gt;Ignite London: Crowd Sourcing a Map of the World&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Tuesday, May 15th 2012, 09:47 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Almost  two weeks ago, I gave a talk at &lt;a href="http://ignitelondon.net"&gt;Ignite London&lt;/a&gt; about &lt;a href="http://openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt;, titled "Crowd Sourcing a Map of the World". Ignite's presentation style is 20 slides which automatically advance every 15 seconds. Having never done &lt;a href="http://derickrethans.nl/talks.html"&gt;this&lt;/a&gt; before I actually wrote the whole talk out. The presentation that I gave slightly diverges from this but I thought it'd still be good to reproduce here. I did add some links to more information, and if you want to see the recording, you can find it at the end of this post.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-01-project-openstreetmap.png" alt="osm-01-project-openstreetmap.png"/&gt;
      &lt;p&gt;1. This talk is about a project, started here in the UK with as its major goal to create a free map of the whole planet. From roads and motorways to country-side footpaths, restaurants and of course pubs. This talk is about OpenStreetMap, the free map of the world.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-02-ordnance-survey.png" alt="osm-02-ordnance-survey.png"/&gt;
      &lt;p&gt;2. There are of course already plenty of mapping solutions available. Maybe one of the best maps can be acquired through Ordnance Survey. They can be regarded as the national authority on this subject. It's however expensive to get access to their maps, especially the very detailed maps from OS MasterMap. Additionally, it's only for the UK.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-03-google-maps.png" alt="osm-03-google-maps.png"/&gt;
      &lt;p&gt;3. Besides the commercial solutions, you might wonder why we simply can't do with GoogleMaps? It's mostly freely available for use and also provides you with satellite imagery and StreetView. They even allow you in some areas to update the map through Google MapMaker.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-04-the-data.png" alt="osm-04-the-data.png"/&gt;
      &lt;p&gt;4. But one thing Google doesn't give you access to, is the data behind the map. All you will ever see, is the rendered map tiles and perhaps some APIs to lookup locations and points of interest. Even for data that you have added yourself through MapMaker.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-05-free-and-open-data.png" alt="osm-05-free-and-open-data.png"/&gt;
      &lt;p&gt;5. Both aspects; the cost of commercial maps, as well as the access to the data that is behind the map tiles is something that the OpenStreetMap project addresses. But which steps have to be taken to obtain this enormous amount of geographical data?&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-06-survey.png" alt="osm-06-survey.png"/&gt;
      &lt;p&gt;6. We start by getting our wellies and trusty GPS out. Maybe even some pen and paper. We find a location that looks rather empty on the map and travel to that area to see what's on the ground. This is step one: data gathering in the field.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-07-urban.png" alt="osm-07-urban.png"/&gt;
      &lt;p&gt;7. In urban areas such as London the roads have often already been mapped and a GPS is not accurate enough to be useful. Then we just use pen and paper to record points of interest, such as shops, landmarks, restaurants and postboxes, my personal favourite.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-08-countryside.png" alt="osm-08-countryside.png"/&gt;
      &lt;p&gt;8. In the country side, donated aerial imagery makes it possible for us to easily trace tracks and footpaths. However, you can't be sure whether the imagery is up-to-date, and you can't always see where fences, streams and local wild life create barriers.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-09-mapping-party.png" alt="osm-09-mapping-party.png"/&gt;
      &lt;p&gt;9. In both situations, surveys are best done in groups: at mapping parties. It helps spread the workload and a larger area can be surveyed in one go. As an additional benefit, it allows us to go the pub and discuss our mapping adventures!&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-10-recording.png" alt="osm-10-recording.png"/&gt;
      &lt;p&gt;10. Doing a survey is important. We take photographs, video and notes with pen and paper of everything that seems to be of interest. This leaves a record that everything we map is actually existing and we can prove that nothing has been copied from other copyrighted maps.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-11-database.png" alt="osm-11-database.png"/&gt;
      &lt;p&gt;11. After collecting the data, we enter it into the database. This includes basic information such as street names, but we also record whether a café has wheelchair access, or whether a pub has wifi. Updates to the map show up on the site close to real time.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-12-tagging.png" alt="osm-12-tagging.png"/&gt;
      &lt;p&gt;12. Every map object has tags associated with it. Tags tell whether a line is a road, or perhaps a fence. All the tags are free form so you can generally add as much information about an object as you want. Sometimes however, this gets slightly out of hand and people tag pandas in trees and eyes on postboxes.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-13-display.png" alt="osm-13-display.png"/&gt;
      &lt;p&gt;13. Once the data has been added to the map, we can make use of it. One of the primary uses is obviously showing the data as map tiles. But with all the extra data, we can generate maps that show all the information you're interested in-and nothing more.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-14-visualisation.png" alt="osm-14-visualisation.png"/&gt;
      &lt;p&gt;14. Clockwise, we have four different visualisations of the map data: we have a &lt;a href="http://www.openstreetmap.org/?lat=51.51647&amp;lon=-0.16968&amp;zoom=17&amp;layers=C"&gt;cycling-specific&lt;/a&gt; style, a style that shows &lt;a href="http://www.openstreetmap.org/?lat=51.51647&amp;lon=-0.16968&amp;zoom=17&amp;layers=T"&gt;transport&lt;/a&gt; routes, a rendering with &lt;a href="http://www.openstreetmap.org/?lat=51.51647&amp;lon=-0.16968&amp;zoom=17&amp;layers=Q"&gt;MapQuest's&lt;/a&gt; style sheets and even a &lt;a href="http://maps.stamen.com/watercolor/#12/51.5168/-0.1515"&gt;water colours&lt;/a&gt; inspired style.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-15-mapquest.png" alt="osm-15-mapquest.png"/&gt;
      &lt;p&gt;15. Having mentioned MapQuest; they were one of the first companies to make use of OpenStreetMap data. They provide, free of charge, map tiles with their own rendering style as well as an instance of &lt;a href="http://wiki.openstreetmap.org/wiki/Nominatim"&gt;Nominatim&lt;/a&gt;, OpenStreetMap's geolocation sister project.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-16-switching.png" alt="osm-16-switching.png"/&gt;
      &lt;p&gt;16. Lots of companies have already switched to OpenStreetMap.  The property search site &lt;a href="http://blog.nestoria.co.uk/why-and-how-weve-switched-away-from-google-ma"&gt;Nestoria&lt;/a&gt; recently switched from using GoogleMaps to OpenStreetMap. Partly because of their costs, but also partly because "The maps are equal or better". geocaching.com, TfL's countdown website and Apple also use OpenStreetMap maps and data.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-17-creative-commons.png" alt="osm-17-creative-commons.png"/&gt;
      &lt;p&gt;17. Although OpenStreetMap provides a free and editable map of the world, there are certain requirements for using the data as well. The most important one is that you always need to attribute the OpenStreetMap project.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-18-switch2osm.png" alt="osm-18-switch2osm.png"/&gt;
      &lt;p&gt;18. In order to help people start using OpenStreetMap for their mapping needs, the Switch2OSM site has been launched. This website provides background information, case studies and technical information on how to use OpenStreetMap data.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-19-we-need-you.png" alt="osm-19-we-need-you.png"/&gt;
      &lt;p&gt;19. Right now, OpenStreetMap has very good data coverage in the country, but we are not nearly finished. A lot of work still has to be done, and we rely on you to improve the data too, even if you add just a postbox.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/osm-20-openstreetmap.png" alt="osm-20-openstreetmap.png"/&gt;
      &lt;p&gt;20. In the last 5 minutes we have looked at what OpenStreetMap is, how the data is gathered and how the data is added to the map. Further more, we had a look at different use cases of the data. OpenStreetMap in the UK: Footpaths and pubs a speciality!&lt;/p&gt;
      &lt;p&gt;And then I planned showing the &lt;a href="http://vimeo.com/derickr/osm-2011"&gt;"Year of Edits"&lt;/a&gt; video, but that sadly didn't work out. I'm including it for good measure here though. (If you want it in HD, follow the &lt;a href="http://vimeo.com/derickr/osm-2011"&gt;link&lt;/a&gt;).&lt;/p&gt;
      &lt;div class="video"&gt;
        &lt;iframe src="http://player.vimeo.com/video/34404102?title=0&amp;byline=0&amp;portrait=0" width=" 599" height=" 337" frameborder="0"/&gt;
        &lt;p&gt;&lt;a href="http://vimeo.com/34404102"/&gt;OpenStreetMap: A Year of Edits (2011)&lt;/p&gt;
      &lt;/div&gt;
      &lt;p&gt;The video of the talk itself is at &lt;a href="http://vimeo.com/41626116"&gt;http://vimeo.com/41626116&lt;/a&gt; and is embedded here:&lt;/p&gt;
      &lt;div class="video"&gt;
        &lt;iframe src="http://player.vimeo.com/video/41626116?title=0&amp;byline=0&amp;portrait=0" width=" 599" height=" 337" frameborder="0"/&gt;
        &lt;p&gt;&lt;a href="http://vimeo.com/41626116"/&gt;Crowdsourcing a Map of the World&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201205150947</guid>
      <pubDate>Tue, 15 May 2012 08:47:00 +0000</pubDate>
    </item>
    <item>
      <title>10 years of Xdebug and Xdebug 2.2.0 released</title>
      <link>http://derickrethans.nl/xdebug-10.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="id_10_years_of_xdebug_and_xdebug_2_2_0_released"/&gt;10 years of Xdebug and Xdebug 2.2.0 released&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Tuesday, May 8th 2012, 14:00 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;img src="http://derickrethans.nl/images/content/cake.jpg" class="right" alt="cake.jpg"/&gt;
      &lt;p&gt;Today it has been ten years since the first release of Xdebug: version 0.7.0. I would like to celebrate this tenth anniversary with a new release: Xdebug 2.2.0. Xdebug 2.2 adds support for PHP 5.4 and provides some new features:&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Colours on the command line&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;First of all there is now &lt;a href="http://xdebug.org/docs/display"&gt;var_dump() overloading&lt;/a&gt; and &lt;a href="http://derickrethans.nl/clicolor-9cr"&gt;colours on the command line&lt;/a&gt;. I've already written about that before, but here are the screenshots again:&lt;/p&gt;
      &lt;p&gt;Linux/Mac:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/cli-color-linux.png" alt="cli-color-linux.png"/&gt;
      &lt;p&gt;Windows:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/cli-color-windows.png" alt="cli-color-windows.png"/&gt;
      &lt;p&gt;You can find an article about this &lt;a href="http://derickrethans.nl/clicolor-9cr"&gt;here&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Better support for closures in stack and function traces&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;Closures are functions that don't have a function name associated with them. Therefore, Xdebug creates a pseudo function in its stack traces.  The stack trace for this example:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
function test1()
{
        $f = function($a, $b) {
                $Q = strlen($a * $b);
                trigger_error('foo');
        };

        $f(5, 25);
}

test1();
?&gt;

&lt;/pre&gt;
      &lt;p&gt;Looks like:&lt;/p&gt;
      &lt;pre&gt;Notice: foo in /tmp/closure-stack-trace.php on line 21

Call Stack:
        0.0009     268464   1. {main}() /tmp/closure-stack-trace.php:0
        0.0026     269288   2. test1() /tmp/closure-stack-trace.php:27
        0.0032     270024   3. {closure:/tmp/closure-stack-trace.php:19-22}($a = 5, $b = 25) /tmp/closure-stack-trace.php:24
        0.0038     270496   4. trigger_error('foo') /tmp/closure-stack-trace.php:21

&lt;/pre&gt;
      &lt;p&gt;In the 3rd line in the call stack you see &lt;code&gt;{closure:/tmp/closure-stack-trace.php:19-22}($a = 5, $b = 25)&lt;/code&gt; where &lt;code&gt;/tmp/closure-stack-trace.php:19-22&lt;/code&gt; contains the filename and line numbers on which the closure is defined at.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;The size of arrays is now shown with the overloaded variable output&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;After this change, each array in the HTML version of the overloaded var_dump() function now looks like:&lt;/p&gt;
      &lt;pre&gt;&lt;b&gt;array&lt;/b&gt; &lt;i&gt;(size=5)&lt;/li&gt;

&lt;/pre&gt;
      &lt;p&gt;Before the change, this was only:&lt;/p&gt;
      &lt;pre&gt;&lt;b&gt;array&lt;/b&gt;

&lt;/pre&gt;
      &lt;p&gt;
        &lt;strong&gt;Added the method call type to xdebug_get_function_stack&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;This changes adds another array element to &lt;a href="http://xdebug.org/docs/stack_trace#xdebug_get_function_stack"&gt;xdebug_get_function_stack()&lt;/a&gt; to show whether it was a static or dynamic function call. For example, for:&lt;/p&gt;
      &lt;pre&gt;new Error_Entry(false, $errno);

&lt;/pre&gt;
      &lt;p&gt;It now adds the &lt;code&gt;["type"]=&gt; string(7) "dynamic"&lt;/code&gt; element to each stack element:&lt;/p&gt;
      &lt;pre&gt;array(6) {
  ["function"]=&gt;
  string(11) "__construct"
  ["type"]=&gt;
  string(7) "dynamic"
  ["class"]=&gt;
  string(11) "Error_Entry"
  ["file"]=&gt;
  string(%d) "%sbug00241.php"
  ["line"]=&gt;
  int(11)


&lt;/pre&gt;
      &lt;p&gt;
        &lt;strong&gt;Extra information to error printouts to tell that the error suppression operator has been ignored due to xdebug.scream&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;When you have the &lt;a href="http://xdebug.org/docs/all_settings#scream"&gt;xdebug.scream&lt;/a&gt; option activated, Xdebug will now tell you when it had any effect on the error reporting with a big "&lt;em&gt;SCREAM: Error suppression ignored for&lt;/em&gt;" warning prepended to the actual error message.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/champagne.jpg" class="left" alt="champagne.jpg"/&gt;
      &lt;p&gt;
        &lt;strong&gt;Changelog&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;You can find the full changelog for Xdebug 2.2.0 at the &lt;a href="http://xdebug.org/updates.php#x_2_2_0"&gt;Xdebug website&lt;/a&gt; where you can also &lt;a href="http://xdebug.org/download.php"&gt;download&lt;/a&gt; the latest version.  If you are using Windows, and don't know which binary to download, please refer to the &lt;a href="http://xdebug.org/wizard.php"&gt;wizard&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Support&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;If you find Xdebug valuable for your PHP development, perhaps you want to support its development by acquiring a "support" contract. See the &lt;a href="http://xdebug.org/buy-support.php"&gt;buying "support"&lt;/a&gt; page if you feel generous.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;What's next?&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;Now Xdebug 2.2 is out of the door, I am looking for new features to add to Xdebug.  What would you like to see added to Xdebug? Please leave a comment here, or add your feature requests at &lt;a href="http://bugs.xdebug.org"&gt;http://bugs.xdebug.org&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201205081400</guid>
      <pubDate>Tue, 08 May 2012 13:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Working at 10gen</title>
      <link>http://derickrethans.nl/mongodb.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="working_at_10gen"/&gt;Working at 10gen&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Thursday, April 5th 2012, 13:00 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;img src="http://derickrethans.nl/images/content/mongodb-logo.png" class="left" alt="mongodb-logo.png"/&gt;
      &lt;p&gt;As of today I am working for &lt;a href="http://10gen.com"&gt;10gen&lt;/a&gt;, the company behind &lt;a href="http://mongodb.org"&gt;MongoDB&lt;/a&gt;. I have been contracting with them for a few months to work on the PHP &lt;a href="http://php.net/mongodb"&gt;driver&lt;/a&gt; for MongoDB. I am now making the switch to a full time position.&lt;/p&gt;
      &lt;p&gt;I am responsible for supporting MongoDB in the PHP ecosystem through driver development, integration with open source tools, community support, and developer advocacy. For now, I will concentrate to get the driver into a better shape, and speaking about MongoDB and PHP.&lt;/p&gt;
      &lt;p&gt;I have already given a few &lt;a href="http://derickrethans.nl/talks.html"&gt;talks&lt;/a&gt; on the subject, and if you would like me to speak at your user group or conference, please let me &lt;a href="http://derickrethans.nl/who.html"&gt;know&lt;/a&gt;. If you have any comments on using MongoDB with PHP, I would love to hear them too.&lt;/p&gt;
      &lt;p&gt;I am looking forwards with the awesome team at 10gen. Both with team in London, as well as with the folks in Palo Alto, New York and Dublin. 10gen is also hiring a few more people for a similar position in New York and Palo Alto. Have a look at the job posting &lt;a href="http://jobvite.com/m?3kW8hfwp"&gt;here&lt;/a&gt; if you are interested.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201204051300</guid>
      <pubDate>Thu, 05 Apr 2012 12:00:00 +0000</pubDate>
    </item>
    <item>
      <title>New in Xdebug 2.2: Colours on the command line</title>
      <link>http://derickrethans.nl/cli-color.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="new_in_xdebug_2_2_colours_on_the_command_line"/&gt;New in Xdebug 2.2: Colours on the command line&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Wednesday, March 21st 2012, 09:43 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;This is the first article in a series about new features in &lt;a href="http://xdebug.org"&gt;Xdebug&lt;/a&gt; 2.2. Besides support for PHP 5.4, there are a few that might be of interest.&lt;/p&gt;
      &lt;p&gt;Xdebug has overloaded &lt;a href="http://php.net/var_dump"&gt;var_dump()&lt;/a&gt; with &lt;a href="http://xdebug.org/docs/all_functions#xdebug_var_dump"&gt;xdebug_var_dump()&lt;/a&gt; for a long time and the overloaded function could be configured with a few configuration settings.  There is &lt;a href="http://xdebug.org/docs/display#var_display_max_data"&gt;xdebug.var_display_max_data&lt;/a&gt; to configure how much of a string should be shown; &lt;a href="http://xdebug.org/docs/display#var_display_max_children"&gt;xdebug.var_display_max_children&lt;/a&gt; to configure how many children in an array should be shown and &lt;a href="http://xdebug.org/docs/display#var_display_max_depth"&gt;xdebug.var_display_max_depth&lt;/a&gt; to configure how many levels "deep" the &lt;code&gt;var_dump()&lt;/code&gt; should go on for. This functionality was available for when PHP had its &lt;a href="http://www.php.net/manual/en/errorfunc.configuration.php#ini.html-errors"&gt;html_errors&lt;/a&gt; setting on as is usually the case in a web environment&lt;a href="http://derickrethans.nl#_footnote_0_1" class="footnote"&gt;1&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;Xdebug 2.2 adds this same functionality to the non-HTML environment: the command line. Now the overloaded &lt;code&gt;var_dump()&lt;/code&gt; and native &lt;code&gt;xdebug_var_dump()&lt;/code&gt; functions also accept the three aforementioned settings:&lt;/p&gt;
      &lt;pre&gt;derick@whisky:~$ php \
        -dxdebug.var_display_max_data=8 \
        -dxdebug.var_display_max_children=4 \
        -r 'var_dump( "a longer string", array( 1, 2, 3, 4, 5, 6, 7 ) );'

&lt;/pre&gt;
      &lt;p&gt;outputs:&lt;/p&gt;
      &lt;pre&gt;string(15) "a longer"...
array(7) {
  [0] =&gt;
  int(1)
  [1] =&gt;
  int(2)
  [2] =&gt;
  int(3)
  [3] =&gt;
  int(4)

  (more elements)...
}

&lt;/pre&gt;
      &lt;p&gt;Now, to be fair. This is all a side effect; and merely an add-on to a patch by &lt;a href="http://mgdm.net"&gt;Michael Maclean&lt;/a&gt;. He wrote a &lt;a href="https://github.com/mgdm/xdebug/commit/23c5739ee923938aba0c029d3971db563cb43606"&gt;patch&lt;/a&gt; that adds colours to the output on the command line by using &lt;a href="http://en.wikipedia.org/wiki/ANSI_escape_code"&gt;ANSI escape codes&lt;/a&gt;. This patch also made the overloaded &lt;code&gt;var_dump()&lt;/code&gt; listen to the limiting settings for variable display. After his patch, the following was the behaviour on the command line as long as &lt;a href="http://en.wikipedia.org/wiki/Stdout#Standard_output_.28stdout.29"&gt;stdout&lt;/a&gt; is a &lt;a href="http://en.wikipedia.org/wiki/Tty_%28Unix%29"&gt;tty&lt;/a&gt; and &lt;a href="http://xdebug.org/docs/display#cli_color"&gt;xdebug.cli_color&lt;/a&gt; is set to &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/cli-color-linux.png" alt="cli-color-linux.png"/&gt;
      &lt;p&gt;I have extended this so that the settings regarding data display also work without &lt;code&gt;xdebug.cli_color&lt;/code&gt; set to &lt;code&gt;1&lt;/code&gt;. Further more, in &lt;a href="http://xdebug.org/updates.php#x_2_2_0rc1"&gt;Xdebug 2.2.0RC1&lt;/a&gt;, setting &lt;code&gt;xdebug.cli_color&lt;/code&gt; to &lt;code&gt;2&lt;/code&gt; forces the colours from being shown, even if stdout is not a tty.&lt;/p&gt;
      &lt;p&gt;Initially, the colour coding of errors and &lt;code&gt;var_dump()&lt;/code&gt; output, would only work on a Unix system where ANSI escape codes are commonly supported. After the release of Xdebug 2.2.0RC1, &lt;a href="http://heyleek.com"&gt;Chris Jones&lt;/a&gt; submitted a &lt;a href="http://bugs.xdebug.org/view.php?id=794"&gt;bug report&lt;/a&gt; suggesting that this functionality could also be available on the Windows console. I wasn't aware that Windows could do this anymore since they dropped &lt;a href="http://en.wikipedia.org/wiki/ANSI_escape_code#Windows_and_DOS"&gt;ANSI.SYS&lt;/a&gt; but apparently there is a tool, &lt;a href="http://adoxa.3eeweb.com/ansicon/"&gt;ANSICON&lt;/a&gt;, that reimplements this. From the next release, Xdebug 2.2.0RC2, Xdebug will now also check whether the &lt;code&gt;ANSICON&lt;/code&gt; environment variable is set, just like Xdebug would check whether stdout is a tty on a Unix platform. As a result, the equivalent console output as shown before looks like the following on Windows (providing ANSICON is installed):&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/cli-color-windows.png" alt="cli-color-windows.png"/&gt;
      &lt;p&gt;Now the only thing left is adding complete documentation for this feature ;-)&lt;/p&gt;
      &lt;p&gt;As always, if you think Xdebug is a valuable tool, have a look at &lt;a href="http://xdebug.org/buy-support.php"&gt;http://xdebug.org/buy-support.php&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
    &lt;ul class="footnotes"&gt;
      &lt;li&gt;
        &lt;a name="_footnote_0_1"&gt;1&lt;/a&gt;
        &lt;p&gt;: Except for in PHP 5.3, where this sadly was turned off by default.&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201203210943</guid>
      <pubDate>Wed, 21 Mar 2012 09:43:00 +0000</pubDate>
    </item>
    <item>
      <title>London at Night</title>
      <link>http://derickrethans.nl/london-at-night.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="london_at_night"/&gt;London at Night&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Saturday, March 17th 2012, 11:45 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;A few days ago I finally wandered into London with a tripod and my camera. I've been meaning to do this for months and take long exposure shots of various places in London, as well as seeing whether I can make cool timelapses.  I've only taken a few pictures near the Thames and the London Eye so far, with one timelapse of the London Eye. I am however planning to return for more. This photography trip also coincided with the &lt;a href="http://en.wikipedia.org/wiki/Conjunction_%28astronomy_and_astrology%29"&gt;conjunction&lt;/a&gt; of Jupiter and Venus.&lt;/p&gt;
      &lt;p&gt;Here are some of the images:&lt;/p&gt;
      &lt;div class="figure"&gt;
        &lt;img src="http://farm8.staticflickr.com/7204/6989474439_38b5ba0a6a_z.jpg" alt="6989474439_38b5ba0a6a_z.jpg"/&gt;
        &lt;p&gt;Jupiter and Venus next to Big Ben&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="figure"&gt;
        &lt;img src="http://farm8.staticflickr.com/7058/6989474675_de7a03a3de_z.jpg" alt="6989474675_de7a03a3de_z.jpg"/&gt;
        &lt;p&gt;A bus streaming past&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class="figure"&gt;
        &lt;img src="http://farm8.staticflickr.com/7204/6989474975_85ae0afca8_z.jpg" alt="6989474975_85ae0afca8_z.jpg"/&gt;
        &lt;p&gt;Houses of parliament&lt;/p&gt;
      &lt;/div&gt;
      &lt;p&gt;And at last item, a timelapse of the London Eye:&lt;/p&gt;
      &lt;div class="video"&gt;
        &lt;iframe src="http://player.vimeo.com/video/38651688?title=0&amp;byline=0&amp;portrait=0" width=" 599" height=" 337" frameborder="0"/&gt;
        &lt;p&gt;&lt;a href="http://vimeo.com/38651688"/&gt;The London Eye, spinning at 75 times its normal speed.&lt;/p&gt;
      &lt;/div&gt;
      &lt;p&gt;This timelapse was recorded with 802 images. Each image is taken 3 seconds after the previous one resulting in a speed-up of 75 times. Lighting has been manually monitored during the taking of the images.&lt;/p&gt;
      &lt;p&gt;The rest of the images are on &lt;a href="http://www.flickr.com/photos/derickrethans/sets/72157629602684483/detail/"&gt;flickr&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201203171145</guid>
      <pubDate>Sat, 17 Mar 2012 11:45:00 +0000</pubDate>
    </item>
    <item>
      <title>Foursquare and OpenStreetMap</title>
      <link>http://derickrethans.nl/foursquare-and-osm.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="foursquare_and_openstreetmap"/&gt;Foursquare and OpenStreetMap&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; Montreal, Canada&lt;/div&gt;
        &lt;div class="date"&gt;Thursday, March 1st 2012, 11:43 EST&lt;/div&gt;
      &lt;/div&gt;
      &lt;img src="http://derickrethans.nl/images/content/foursquare-osm.png" class="left" alt="foursquare-osm.png"/&gt;
      &lt;p&gt;Yesterday, FourSquare &lt;a href="http://blog.foursquare.com/2012/02/29/foursquare-is-joining-the-openstreetmap-movement-say-hi-to-pretty-new-maps/"&gt;announced&lt;/a&gt; that they are "joining the OpenStreetMap movement", meaning that the now use &lt;a href="http://www.openstreetmap.org/"&gt;OpenStreetMap&lt;/a&gt; data for their map tiles. With their own map styles and using &lt;a href="http://mapbox.com"&gt;MapBox&lt;/a&gt; for rendering their styles. This is &lt;strong&gt;amazing&lt;/strong&gt; news I think.&lt;/p&gt;
      &lt;p&gt;Of course, as with many changes, some people are &lt;a href="http://blog.foursquare.com/2012/02/29/foursquare-is-joining-the-openstreetmap-movement-say-hi-to-pretty-new-maps/#comment-453335876"&gt;happy&lt;/a&gt; but there are others that &lt;a href="http://blog.foursquare.com/2012/02/29/foursquare-is-joining-the-openstreetmap-movement-say-hi-to-pretty-new-maps/#comment-453041717a"&gt;complain&lt;/a&gt; that the map data just isn't up to standards yet for their area. That's a fair point as OpenStreetMap does not have all roads and points-of-interest (POIs) of every city and town in the whole world. The geographical data has mostly been contributed by people on the ground with GPS devices through so called &lt;a href="http://wiki.openstreetmap.org/wiki/Mapping_party"&gt;mapping parties&lt;/a&gt;. Both in places like &lt;a href="http://wiki.openstreetmap.org/wiki/London/Summer_2011_mapping_parties"&gt;London&lt;/a&gt; as well as in slums such as &lt;a href="http://mapkibera.org/"&gt;Kibera&lt;/a&gt;. For a look at the progress over such a weekend, check this &lt;a href="http://vimeo.com/37255594"&gt;video&lt;/a&gt; or have a look at &lt;a href="http://drck.me/osmyoe11-9nz"&gt;"OpenStreetMap: A Year of Edits"&lt;/a&gt; for an animation showing all the edits in 2011.&lt;/p&gt;
      &lt;p&gt;Foursquare is all about spamming twitter, I mean, checking into venues to acquire points and badges. OpenStreetMap is all about having a database of geographical data, and that is not only roads! I've written on OpenStreetMap &lt;a href="http://drck.me/what-is-osm-8my"&gt;before&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;A venue is a POI in the OpenStreetMap jargon. It makes a whole lot of sense to keep only one database of these POIs/venues. The venues are added (and fixed) by foursquare users in the first place so getting that data into OpenStreetMap would be awesome.&lt;/p&gt;
      &lt;p&gt;I think this is a great opportunity for fourquare to contribute the venue data to improve OpenStreetMap. I think in this case, there needs to be some form of review process before they can be added to OpenStreetMap, or perhaps consolidated with already existing POI data. This is going be an interesting challenge, and luckily foursquare already is &lt;a href="http://blog.foursquare.com/2012/02/29/foursquare-is-joining-the-openstreetmap-movement-say-hi-to-pretty-new-maps/#comment-452722147"&gt;toying&lt;/a&gt; with how to improve OpenStreetMap's data.&lt;/p&gt;
      &lt;p&gt;Besides venues, OpenStreetMap also contains roads and in places those roads are missing or don't have names. Perhaps foursquare can even sponsor mapping parties in the "empty" areas.  In the end, a free-to-use open geographic database is what is beneficial to everybody.&lt;/p&gt;
      &lt;p&gt;For more information on OpenStreetMap, have a look at its &lt;a href="http://wiki.openstreetmap.org/wiki/Main_Page"&gt;wiki&lt;/a&gt; or drop by on &lt;a href="http://wiki.openstreetmap.org/wiki/Irc"&gt;IRC&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201203011143</guid>
      <pubDate>Thu, 01 Mar 2012 16:43:00 +0000</pubDate>
    </item>
    <item>
      <title>To GMT or not to GMT</title>
      <link>http://derickrethans.nl/gmt-being-tricky.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="to_gmt_or_not_to_gmt"/&gt;To GMT or not to GMT&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; Montreal, Canada&lt;/div&gt;
        &lt;div class="date"&gt;Wednesday, February 29th 2012, 11:18 EST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;A leap day with a post on Date/Time issues seems fitting...&lt;/p&gt;
      &lt;p&gt;Earlier today, on &lt;a href="https://twitter.com/skoop/status/174794576312287232"&gt;twitter&lt;/a&gt;, &lt;a href="https://twitter.com/skoop"&gt;@skoop&lt;/a&gt; asked: &lt;em&gt;"dear #lazyweb, when I use DateTimeZone('GMT'), why does format('e') output UTC?"&lt;/em&gt; What he means is that:&lt;/p&gt;
      &lt;pre&gt;$date = new DateTime('now', new DateTimeZone('GMT'));
echo $date-&gt;format(DateTime::RFC2822 . ' e' );

&lt;/pre&gt;
      &lt;p&gt;which shows:&lt;/p&gt;
      &lt;pre&gt;Wed, 29 Feb 2012 16:26:23 +0000 UTC

&lt;/pre&gt;
      &lt;p&gt;As you can see that has &lt;code&gt;UTC&lt;/code&gt; and not &lt;code&gt;GMT&lt;/code&gt; as you might expect.&lt;/p&gt;
      &lt;p&gt;If you look closely at the &lt;a href="http://ca.php.net/manual/en/timezones.others.php"&gt;documentation&lt;/a&gt; for the "Other" group of timezones, it lists with the &lt;code&gt;GMT&lt;/code&gt; timezone as warning: &lt;em&gt;"Please do not use any of the timezones listed here (besides UTC), they only exist for backward compatible reasons."&lt;/em&gt; If you use &lt;code&gt;GMT&lt;/code&gt; as timezone identifier in the constructor to &lt;code&gt;DateTimeZone&lt;/code&gt;, PHP will instead use the correct &lt;code&gt;UTC&lt;/code&gt; in output. When you create a &lt;code&gt;DateTimeZone&lt;/code&gt; object like this, you will always get a "type 3" DateTimeZone object:&lt;/p&gt;
      &lt;pre&gt;$date = new DateTime('now', new DateTimeZone('GMT'));
var_dump($date);

&lt;/pre&gt;
      &lt;p&gt;which shows:&lt;/p&gt;
      &lt;pre&gt;object(DateTime)#1 (3) {
  ["date"]=&gt;
  string(19) "2012-02-29 16:30:51"
  ["timezone_type"]=&gt;
  int(3)
  ["timezone"]=&gt;
  string(3) "UTC"
}

&lt;/pre&gt;
      &lt;p&gt;Now apparently some systems &lt;em&gt;*cough*Silverlight*cough*&lt;/em&gt; require &lt;code&gt;GMT&lt;/code&gt; to be used.  &lt;code&gt;GMT&lt;/code&gt; is &lt;strong&gt;not&lt;/strong&gt; a timezone, but just a timezone abbreviation meant for &lt;strong&gt;output only&lt;/strong&gt;.  Read more about that in the article &lt;a href="http://drck.me/lsawtdwt-6ye"&gt;"Leap Seconds and What To Do With Them"&lt;/a&gt;.  However, if it is necessary you can create a &lt;code&gt;DateTime&lt;/code&gt; object with a different timezone type. In this case you want a "type 2" timezone associated with the &lt;code&gt;DateTime&lt;/code&gt; object. You do that by simply forcing that timezone abbreviation when instantiating a &lt;code&gt;DateTime&lt;/code&gt; object:&lt;/p&gt;
      &lt;pre&gt;$date = new DateTime('today GMT');
var_dump( $date );

&lt;/pre&gt;
      &lt;p&gt;which shows:&lt;/p&gt;
      &lt;pre&gt;object(DateTime)#1 (3) {
  ["date"]=&gt;
  string(19) "2012-02-29 16:32:16"
  ["timezone_type"]=&gt;
  int(2)
  ["timezone"]=&gt;
  string(3) "GMT"
}

&lt;/pre&gt;
      &lt;p&gt;Things like this also work:&lt;/p&gt;
      &lt;pre&gt;$date = new DateTime( "GMT" );
$date-&gt;setDate( 2012, 2, 19 );
var_dump( $date );

&lt;/pre&gt;
      &lt;p&gt;And of course, this is not limited to &lt;code&gt;GMT&lt;/code&gt; only:&lt;/p&gt;
      &lt;pre&gt;$date = new DateTime( "EST" );
$date-&gt;setDate( 2012, 2, 19 );
var_dump( $date );

&lt;/pre&gt;
      &lt;p&gt;which shows:&lt;/p&gt;
      &lt;pre&gt;object(DateTime)#1 (3) {
  ["date"]=&gt;
  string(19) "2012-02-19 16:37:58"
  ["timezone_type"]=&gt;
  int(2)
  ["timezone"]=&gt;
  string(3) "EST"
}


&lt;/pre&gt;
      &lt;p&gt;As a reminder of the three different types of timezones that can be attached to &lt;code&gt;DateTime&lt;/code&gt; objects:&lt;/p&gt;
      &lt;ol&gt;
        &lt;li&gt;
          &lt;p&gt;A UTC offset, such as in &lt;code&gt;new DateTime( "2012-02-29 -0500" );&lt;/code&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;A timezone abbreviation, such as in &lt;code&gt;new DateTime( "2012-02-29 EST" );&lt;/code&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;A timezone identifier, such as in &lt;code&gt;new DateTime( "2012-02-29 America/Montreal" );&lt;/code&gt;&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ol&gt;
      &lt;p&gt;Please also be aware that &lt;em&gt;only&lt;/em&gt; &lt;code&gt;DateTime&lt;/code&gt; objects with "type 3" timezones attached to them will calculate correctly over Daylight Saving Time boundaries.&lt;/p&gt;
      &lt;p&gt;If you want to learn more about Dates and Times, and how to use them with PHP, please get a copy of my book &lt;a href="http://phpdatebook.com/"&gt;"php|architect's Guide to Date and Time Programming"&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201202291118</guid>
      <pubDate>Wed, 29 Feb 2012 16:18:00 +0000</pubDate>
    </item>
    <item>
      <title>Random Bugs and Testing RCs</title>
      <link>http://derickrethans.nl/random-bugs-and-testing-rcs.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="random_bugs_and_testing_rcs"/&gt;Random Bugs and Testing RCs&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Friday, February 24th 2012, 13:00 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;At the &lt;a href="http://phpconference.co.uk/"&gt;PHP UK Conference&lt;/a&gt; &lt;a href="http://twitter.com/rasmus"&gt;Rasmus&lt;/a&gt; mentioned that he wants more people contributing to PHP. There are plenty of ways how you can do that.&lt;/p&gt;
      &lt;p&gt;The first one is testing release candidates RCs of PHP releases. You can do a very basic test by running "make test" after compiling PHP, but it's even a lot more important to test your &lt;em&gt;own&lt;/em&gt; code with the RCs. This often catches more things as the PHP Development Team doesn't quite know how everybody uses PHP. It's a little bit late in the game now for PHP 5.4, but head over to &lt;a href="http://qa.php.net/rc.php"&gt;http://qa.php.net/rc.php&lt;/a&gt; for a quick intro and a link to where to download the RC8. PHP 5.4.0 is not released yet, so testing the RC is still very valuable. Hurry up though, as this is most likely the last RC for 5.4.0! Also, you are not allowed to complain about PHP 5.4 breaking stuff unless you've tested RCs :-)&lt;/p&gt;
      &lt;p&gt;The second thing that Rasmus brought up is a new feature on &lt;a href="http://bugs.php.net"&gt;http://bugs.php.net&lt;/a&gt; It's modelled like the "random cute cat picture" features that sites like &lt;a href="http://cuteoverload.com"&gt;http://cuteoverload.com&lt;/a&gt; use for giving you a random cat picture. Except that we don't show cute cats, but a random PHP bug. If you have a few spare minutes go hit &lt;a href="http://bugs.php.net/random"&gt;http://bugs.php.net/random&lt;/a&gt; until there is either an unconfirmed bug report that needs triage, or perhaps you can just fix it because you're a C wizzard. This is hopefully a better time waster than random cute cats.&lt;/p&gt;
      &lt;p&gt;Oh, yeah, go test the PHP 5.4.0 RC! 🐱&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201202241300</guid>
      <pubDate>Fri, 24 Feb 2012 13:00:00 +0000</pubDate>
    </item>
    <item>
      <title>OpenStreetMap: A Year of Edits</title>
      <link>http://derickrethans.nl/year-of-edits.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="openstreetmap_a_year_of_edits"/&gt;OpenStreetMap: A Year of Edits&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Sunday, January 1st 2012, 00:00 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;In the past weeks I've been working on some visualisations related to additions and changes being made to OpenStreetMap. To start of the new year, I hereby present: &lt;strong&gt;OpenStreetMap: A Year of Edits (2011)&lt;/strong&gt;:&lt;/p&gt;
      &lt;div class="video"&gt;
        &lt;iframe src="http://player.vimeo.com/video/34404102?title=0&amp;byline=0&amp;portrait=0" width=" 599" height=" 337" frameborder="0"/&gt;
        &lt;p&gt;&lt;a href="http://vimeo.com/34404102"/&gt;OpenStreetMap: A Year of Edits (2011)&lt;/p&gt;
      &lt;/div&gt;
      &lt;p&gt;You can see the video in HD on &lt;a href="http://vimeo.com/derickr/osm-2011"&gt;Vimeo&lt;/a&gt;. &lt;strong&gt;Happy New Year!&lt;/strong&gt;&lt;/p&gt;
      &lt;p&gt;
        &lt;em&gt;How Did He Do That?&lt;/em&gt;
      &lt;/p&gt;
      &lt;p&gt;This animation is all made with Open Source software. I haven't had the time to clean up the code to make it releasable yet, but I am intending to do that in the near feature and add it to my &lt;a href="https://github.com/derickr/osm-tools"&gt;OpenStreetMap tools&lt;/a&gt; git repository on github.&lt;/p&gt;
      &lt;p&gt;The first thing I did, was download all the hourly replication files from &lt;a href="http://planet.openstreetmap.org/hour-replicate"&gt;http://planet.openstreetmap.org/hour-replicate&lt;/a&gt; for the year.&lt;/p&gt;
      &lt;p&gt;With a script, I scanned over all those XML files and for every three hours I created an image showing the edits of those last three hours (in white), as well as all the other edits in the background (in purple). With 4 frames per day, this gives me 1460 frames.&lt;/p&gt;
      &lt;p&gt;Each of the frames is an equirectangular projection which I then map onto a sphere with a faded background of "earthmap10k" of &lt;a href="http://planetpixelemporium.com/earth.html"&gt;http://planetpixelemporium.com/earth.html&lt;/a&gt; (I downloaded it &lt;em&gt;years&lt;/em&gt; ago when it was still free to download). For the 3D rendering of the Earth with the edits layed on top of it I used &lt;a href="http://www.povray.org/"&gt;POV-Ray&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;I generated two different loops so that I can make two full rotations at different angles. This gives me in total 2882 frames which is about two minutes. The POV-Ray generated images I post-processed by overlaying the progress bar in the lower left and added the fading and merging effects. Then I used &lt;a href="http://www.mplayerhq.hu/"&gt;mencoder&lt;/a&gt; to create a MPEG video out of it.  Finally I added the &lt;a href="http://www.archive.org/details/TBECD005-MP3-192k-VBR"&gt;sound track&lt;/a&gt; again by using mencoder and uploaded it to &lt;a href="http://vimeo.com/derickr/osm-2011"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201201010000</guid>
      <pubDate>Sun, 01 Jan 2012 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Twig extension</title>
      <link>http://derickrethans.nl/twig-extension.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="twig_extension"/&gt;Twig extension&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Monday, November 21st 2011, 09:20 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;A while ago, &lt;a href="http://github.com/fabpot"&gt;Fabien&lt;/a&gt; asked me to have a look at porting one of &lt;a href="http://twig.sensiolabs.org/"&gt;Twig's&lt;/a&gt; slowest methods, &lt;code&gt;TwigTemplate::getAttribute()&lt;/code&gt;, into a PHP extension. It is a complex method that does a lot of different checks and look-ups. Fabien's benchmarks showed that this method was responsible for quite a large amount of time. On top of that, it didn't seem that it could be optimised any further as PHP code itself. Seeing that it was very likely that this method would be a lot faster when written in C, &lt;a href="http://sensiolabs.com/"&gt;SensioLabs&lt;/a&gt; decided to sponser me for the development of a port of this method into a PHP extension.&lt;/p&gt;
      &lt;p&gt;Over the next few months I've worked on re-implementing just this method as a C-function in &lt;a href="https://github.com/derickr/twig-ext"&gt;twig-ext&lt;/a&gt;: &lt;code&gt;twig_template_get_attributes()&lt;/code&gt;. From initial benchmarks it looks like this function as implemented in the extension gives about a 15% speed increase while rendering templates. Twig's compiled templates directly contain a call to this function (as opposed to marshal it through the original &lt;code&gt;TwigTemplate::getAttribute()&lt;/code&gt; method) for additional performance. This probably means that you'll have to remove your compiled templates cache while upgrading.&lt;/p&gt;
      &lt;p&gt;The extension at &lt;a href="http://github.com/derickr/twig-ext"&gt;http://github.com/derickr/twig-ext&lt;/a&gt; has now been merged, via &lt;a href="http://github.com/derickr/Twig"&gt;http://github.com/derickr/Twig&lt;/a&gt;, into &lt;a href="http://github.com/fabpot/Twig"&gt;http://github.com/fabpot/Twig&lt;/a&gt;. The plan is that this new improvement is going to be part of Twig 1.4.&lt;/p&gt;
      &lt;p&gt;If you are also interested in having some of your PHP code ported into a PHP extension in C, please feel free to &lt;a href="http://derickrethans.nl/who.html"&gt;contact&lt;/a&gt; me.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201111210920</guid>
      <pubDate>Mon, 21 Nov 2011 09:20:00 +0000</pubDate>
    </item>
    <item>
      <title>XFCE and moving windows around with the keyboard</title>
      <link>http://derickrethans.nl/xfce-and-keyboard.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xfce_and_moving_windows_around_with_the_keyboard"/&gt;XFCE and moving windows around with the keyboard&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Thursday, November 17th 2011, 09:31 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;During a recent &lt;code&gt;apt-get update &amp;&amp; apt-get dist-upgrade&lt;/code&gt; I suddenly found myself with the horrors that are Gnome 3 and the Gnome shell, and of course, at the least opportune moment when I was actually planning on heading into an office (more about that later). I've always been a big &lt;a href="http://xwinman.org/sawfish.php"&gt;Sawfish&lt;/a&gt; fan, and was annoyed when Gnome replaced that with &lt;a href="http://xwinman.org/metacity.php"&gt;Metacity&lt;/a&gt;, but I always managed to get Sawfish back up again.  No more luck now, and without a &lt;a href="http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=sawfish-gnome;dist=unstable"&gt;Debian package maintainer&lt;/a&gt; I decided to try out &lt;a href="http://xwinman.org/xfce.php"&gt;XFCE&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;I found &lt;a href="http://xwinman.org/xfce.php"&gt;XFCE&lt;/a&gt; to be as easy to use with the keyboard as Sawfish but with one big missing issue: I couldn't change the size and position of windows at the keyboard anymore. I hardly use a mouse as it hurts too much, and always relied on those keyboard shortcuts to position my windows so I was quite a bit at a loss. After some searching I ran into a post on &lt;a href="http://old.nabble.com/New-Behavior-about-moving-windows.-td22293281.html"&gt;nabble&lt;/a&gt; that contained a script that almost did what I want. It uses a bunch of standard X tools (&lt;a href="http://www.xfree86.org/current/xprop.1.html"&gt;xprop&lt;/a&gt; and &lt;a href="http://www.xfree86.org/4.2.0/xwininfo.1.html"&gt;xwininfo&lt;/a&gt;) to find some information about the active window and its properties. Then depending on some parameters it would use &lt;a href="http://tomas.styblo.name/wmctrl/"&gt;wmctrl&lt;/a&gt; to move and/or resize the window. For example: &lt;code&gt;./bin/window-geometry-control.sh -m left&lt;/code&gt; would move the window 1 pixel to the left.&lt;/p&gt;
      &lt;p&gt;That's all good, but way too slow. I basically just want to bump my windows to the top, right, bottom and left sides of my screen. So besides the simple move and resize, I added what Sawfish originally also had: move left/right/top and bottom; and well as resize-to left/right/top and bottom. Now with the command &lt;code&gt;./bin/window-geometry-control -b left&lt;/code&gt; I can move the active window all the way to the left, and with &lt;code&gt;./bin/window-geometry-control -s bottom&lt;/code&gt; I can resize my window from its current position all the way to the bottom of the screen. To each of the four directions and two methods I assigned keyboard shortcuts in &lt;code&gt;xfce4-settings-manager&lt;/code&gt;, Keyboard, Application Shortcuts.&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/xfce-keyboard.png" alt="xfce-keyboard.png"/&gt;
      &lt;p&gt;The screenshot above shows those assigned keyboard shortcuts. I've put the modified script on &lt;a href="https://github.com/derickr/scripts/blob/master/window-geometry-control.sh"&gt;github&lt;/a&gt;. As you can see I hardcoded the width and height of my own screen in it. Feel free to make this dynamic and send a pull request.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201111170931</guid>
      <pubDate>Thu, 17 Nov 2011 09:31:00 +0000</pubDate>
    </item>
    <item>
      <title>Multiple PHP versions set-up</title>
      <link>http://derickrethans.nl/multiple-php-version-setup.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="multiple_php_versions_set-up"/&gt;Multiple PHP versions set-up&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Monday, November 7th 2011, 09:11 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;For many of my projects (both &lt;a href="http://derickrethans.nl/projects.html"&gt;hobby&lt;/a&gt; and &lt;a href="http://derickrethans.nl/who.html#derickrethansltd"&gt;commercial&lt;/a&gt;) I need to support many different PHP configurations. Not only just different PHP versions, but also debug builds, ZTS builds and 32-bit builds. In order to be able to test and build extensions against all those different PHP configurations I have adopted a simple method that I'm sharing with you here.&lt;/p&gt;
      &lt;p&gt;The major part of it is that I use a different installation prefix for every configuration of PHP that I make. Right now, &lt;code&gt;ls /usr/local/php&lt;/code&gt; shows:&lt;/p&gt;
      &lt;pre&gt;5.1dev  5.3.2  5.3.8dev  5.3dev-32bit    5.3dev-zts  5.4dev      trunk
5.2dev  5.3.7  5.3dev    5.3dev-nodebug  5.4.0beta1  5.4dev-zts

&lt;/pre&gt;
      &lt;p&gt;There are two types of PHP installs that I make: "dev" versions from SVN branches, and "release" versions build from SVN tags. From the list above you see I have the SVN versions of 5.1, 5.2, 5.3.8, 5.3 (in various forms) and 5.4 (both normal, and ZTS).&lt;/p&gt;
      &lt;p&gt;I have a &lt;a href="http://derickrethans.nl/files/php-build.sh.txt"&gt;script&lt;/a&gt; to compile PHP which whatever combination I want: version, debug (default) or non-debug, normal (default) or ZTS; and 64-bit (default) or 32-bit. The configure options are nicely hardcoded :-)&lt;/p&gt;
      &lt;p&gt;The scripts accept arguments in a specific order:&lt;/p&gt;
      &lt;pre&gt;version ["debug"|"nodebug" [, "no-zts"|"zts" [, ""|"32bit" ] ] ]

&lt;/pre&gt;
      &lt;p&gt;For a simple 5.3dev build I run:&lt;/p&gt;
      &lt;pre&gt;./build 5.3dev

&lt;/pre&gt;
      &lt;p&gt;This compiles PHP 5.3 from SVN, in debug mode, without ZTS and for the 64-bit architecture. Something more exotic variants could be:&lt;/p&gt;
      &lt;pre&gt;./build 5.3.8 debug zts
./build 5.4dev nodebug no-zts 32bit

&lt;/pre&gt;
      &lt;p&gt;Each invocation of the script will configure and build PHP, and then install into &lt;code&gt;/usr/local/php/{{variant}}&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;The script also has a hard coded location where the PHP sources are. In my case, that's a &lt;a href="https://wiki.php.net/vcs/svnfaq#sparse_directory_checkout_instructions"&gt;sparse checkout&lt;/a&gt; into &lt;code&gt;/home/derick/dev/php/php-src&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;With the help of a small &lt;code&gt;.bashrc&lt;/code&gt; snippet:&lt;/p&gt;
      &lt;pre&gt;function pe () {
        version=$1
        shift

        if [ "$#" == "0" ]; then
                export PATH=/usr/local/php/${version}/bin:/usr/local/bin:/usr/bin:/bin
        else
                PATH=/usr/local/php/${version}/bin:$PATH $@
        fi
}

&lt;/pre&gt;
      &lt;p&gt;I can now easily switch between PHP versions by typing on the shell:&lt;/p&gt;
      &lt;pre&gt;pe 5.3dev

&lt;/pre&gt;
      &lt;p&gt;or:&lt;/p&gt;
      &lt;pre&gt;pe 5.4dev-zts

&lt;/pre&gt;
      &lt;p&gt;And each version will have a totally separated environment for me to install PEAR packages and PECL extensions in, and do my own extension development. Of course, each separated environment also comes with its own &lt;code&gt;php.ini&lt;/code&gt; file (in &lt;code&gt;/usr/local/php/{{variant}}/lib/php.ini&lt;/code&gt;).&lt;/p&gt;
      &lt;p&gt;This set-up makes my life a whole lot easier, and I hope it is useful for you as well. Thanks for listening!&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201111070911</guid>
      <pubDate>Mon, 07 Nov 2011 09:11:00 +0000</pubDate>
    </item>
    <item>
      <title>Xdebug's Code Coverage speedup</title>
      <link>http://derickrethans.nl/xdebug-codecoverage-speedup.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="xdebug_s_code_coverage_speedup"/&gt;Xdebug's Code Coverage speedup&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Friday, September 23rd 2011, 09:23 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Besides a debugging and development aid, &lt;a href="http://xdebug.org"&gt;Xdebug&lt;/a&gt; also implements the back-end code to provide code coverage information for use with &lt;a href="http://www.phpunit.de"&gt;PHPUnit&lt;/a&gt;. Code coverage tells you how much of your code base is actually being tested by your unit tests. It's a very useful feature, but sadly, it slows down PHP's execution quite a lot. One part of this slowdown is the overhead to record the information internally, but another part is because I have to overload lots of opcodes. (Opcodes are PHP's internal execution units, similar to &lt;a href="http://en.wikipedia.org/wiki/Assembler_%28computer_programming%29#Assembly_language"&gt;assembler&lt;/a&gt; instructions) They are always overloaded even if code coverage is not used, because it's only safe to overload them for the whole request.&lt;/p&gt;
      &lt;p&gt;The upcoming Xdebug 2.2 has a few changes to improve code coverage performance. First of all, the speed with which information about code coverage is recorded has been improved by &lt;a href="https://github.com/taavi/xdebug/commits/coverage_line_array"&gt;contributions&lt;/a&gt; by &lt;a href="https://github.com/taavi"&gt;Taavi Burns&lt;/a&gt;. And secondly, Xdebug 2.2 features a new setting, &lt;code&gt;xdebug.coverage_enable&lt;/code&gt; with which it is possible to disable the overloading of code coverage specific opcodes. By default that setting will still be &lt;code&gt;on&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;Just to show how those improvements have effect on the speed, I've run a benchmark (running &lt;a href="http://incubator.apache.org/zetacomponents/"&gt;Apache Zeta Components&lt;/a&gt; Graph's tests) to compare Xdebug 2.1.2 against Xdebug 2.2-dev.&lt;/p&gt;
      &lt;p&gt;The results are as follows:&lt;/p&gt;
      &lt;table&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;Version  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;With CC  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;Without CC  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;With coverage_enable=0  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;Without Xdebug&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;2.1.2    &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;06:44    &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;00:49       &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;&lt;em&gt;not available&lt;/em&gt;         &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;00:32&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;2.2-dev  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;05:37    &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;00:48       &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;00:46                   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;00:32&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
      &lt;p&gt;Another benchmark, run by &lt;a href="https://twitter.com/#!/rossmcf"&gt;Ross McFarlane&lt;/a&gt; gives: &lt;a href="https://twitter.com/#!/rossmcf/status/116086201391398913"&gt;@derickr Based on 3 runs each, execution of 254 tests with 1070 assertions has dropped from 19s to 12s. Nice work!&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;In Xdebug 2.2 I would also like to introduce &lt;em&gt;modes&lt;/em&gt;. Each mode will set a default configuration for Xdebug's setting to be the most optimal for that specific tasks. Examples of tasks could be: "profiling", "debugging" or "tracing". Let me know (in the comments) whether you think that's a good idea.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201109230923</guid>
      <pubDate>Fri, 23 Sep 2011 08:23:00 +0000</pubDate>
    </item>
    <item>
      <title>Remote Debugging PHP with a Firewall in the Way</title>
      <link>http://derickrethans.nl/debugging-with-xdebug-and-firewalls.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="remote_debugging_php_with_a_firewall_in_the_way"/&gt;Remote Debugging PHP with a Firewall in the Way&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; London, UK&lt;/div&gt;
        &lt;div class="date"&gt;Thursday, August 25th 2011, 21:42 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The PHP debugging extension &lt;a href="http://xdebug.org"&gt;Xdebug&lt;/a&gt; has "remote" &lt;a href="http://xdebug.org/docs/remote"&gt;debugging&lt;/a&gt; capabilities for single-step debugging PHP applications. This works by setting your favourite IDE into listening mode and instructing Xdebug (with one of the handy browser &lt;a href="http://xdebug.org/docs/remote#browser-extensions"&gt;extensions&lt;/a&gt; for example) to initiate debugging. When Xdebug is instructed it tries to make a connection to the IP address and port number that are &lt;a href="http://xdebug.org/docs/remote#remote_host"&gt;configured&lt;/a&gt; in php.ini. On this IP &lt;a href="http://xdebug.org/docs/remote#remote_host"&gt;address&lt;/a&gt; and &lt;a href="http://xdebug.org/docs/remote#remote_port"&gt;port&lt;/a&gt; Xdebug expects to find a listening IDE. This IP address can just be &lt;code&gt;127.0.0.1&lt;/code&gt; in case your IDE and web server/CLI script run on the same machine. But as Xdebug supports remote debugging, PHP/Xdebug could also be running on a totally different machine than your IDE. In that case, you need to pick the IP address of the machine on which the IDE is running as the configuration value for &lt;code&gt;xdebug.remote_host&lt;/code&gt;. Alternatively you can set &lt;code&gt;xdebug.remote_connect_back&lt;/code&gt; to true, so that Xdebug may simply pick up your client machine's IP address from the HTTP headers.&lt;/p&gt;
      &lt;p&gt;There could however be a firewall in the way that prevents Xdebug connecting directly to your IDE's IP address. That can be because the network you are on employs &lt;a href="http://en.wikipedia.org/wiki/Network_address_translation"&gt;NAT&lt;/a&gt; in which case you could try (to convince) to get your system administrator to install a &lt;a href="https://github.com/derickr/dbgp"&gt;DBGp&lt;/a&gt; &lt;a href="http://derickrethans.nl/debugging-with-multiple-users.html"&gt;proxy&lt;/a&gt;. In some cases, he might not be willing to do so, or perhaps, there is simply a black box that doesn't allow either a proxy to be run on it, or port forwarding to be set-up on. In this case, there is no way Xdebug can connect to your IDE's IP address and port. Or is there?&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Breaking the Firewall Down&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;There is another solution, at least, if you have &lt;a href="http://en.wikipedia.org/wiki/Secure_Shell"&gt;SSH&lt;/a&gt; access to the development machine where Xdebug is running on. In this case, you can simply ssh in and set-up a tunnel:&lt;/p&gt;
      &lt;pre&gt;ssh -R 9000:localhost:9000 username@dev.example.com

&lt;/pre&gt;
      &lt;p&gt;This command opens up port &lt;code&gt;9000&lt;/code&gt;, configured with the first &lt;code&gt;9000&lt;/code&gt; in the command, for listening on the machine where you ssh-ed into. Every connection that is made to this port is then forwarded to &lt;code&gt;localhost:9000&lt;/code&gt;, which in this case is port &lt;code&gt;9000&lt;/code&gt; on the machine from where you ran the &lt;code&gt;ssh&lt;/code&gt; command from. When you set Xdebug's &lt;code&gt;xdebug.remote_host&lt;/code&gt; setting to &lt;code&gt;localhost&lt;/code&gt; and &lt;code&gt;xdebug.remote_port&lt;/code&gt; to &lt;code&gt;9000&lt;/code&gt; you know have instructed Xdebug to connect to your SSH-tunneled connection which is forwarded to your local port &lt;code&gt;9000&lt;/code&gt;. And that is exactly where your IDE is listening for incoming debugging connections. Result: Firewall circumvented.&lt;/p&gt;
      &lt;p&gt;If you are so unfortunate to be using Windows on the client side then you don't have the luxury of being able to use the simple SSH client. However, you can set-up tunnels with &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/"&gt;putty&lt;/a&gt; as well. After configuring your normal session, go to the &lt;code&gt;Connection&lt;/code&gt;, &lt;code&gt;SSH&lt;/code&gt;, &lt;code&gt;Tunnels&lt;/code&gt; section of the configuration and fill in &lt;code&gt;Source port&lt;/code&gt; and &lt;code&gt;Destination&lt;/code&gt;, and select &lt;code&gt;Remote&lt;/code&gt;, just like in this screen shot:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/putty-tunnel-settings.png" class="center" alt="putty-tunnel-settings.png"/&gt;
      &lt;p&gt;Then click the &lt;code&gt;Add&lt;/code&gt; button and you will see the following on your screen:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/putty-tunnel-result.png" class="center" alt="putty-tunnel-result.png"/&gt;
      &lt;p&gt;Don't forget to go back to the &lt;code&gt;Session&lt;/code&gt; tab and press save. You're now ready to login and when you do so an SSH tunnel will be created just like in the Unix case above.&lt;/p&gt;
      &lt;p&gt;You can check whether it worked by running: &lt;code&gt;netstat -a -n | grep 9000&lt;/code&gt; on the SSH prompt after logging in. You should then see:&lt;/p&gt;
      &lt;pre&gt;derick@xdebug:~$ netstat -a -n | grep 9000
tcp        0      0 0.0.0.0:9000            0.0.0.0:*               LISTEN
tcp6       0      0 :::9000                 :::*                    LISTEN

&lt;/pre&gt;
      &lt;p&gt;The &lt;code&gt;tcp6&lt;/code&gt; portion might not be there, but that's all right. There, even with Windows: Firewall circumvented.&lt;/p&gt;
      &lt;div class="flattr"&gt;
        &lt;a class="FlattrButton" rev="flattr;button:compact;" style="display: none" href="http://derickrethans.nl"/&gt;
        &lt;noscript&gt;
          &lt;a href="http://flattr.com/thing/429095/Derick-Rethans-website"&gt;
            &lt;img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this"/&gt;
          &lt;/a&gt;
        &lt;/noscript&gt;
      &lt;/div&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201108252142</guid>
      <pubDate>Thu, 25 Aug 2011 20:42:00 +0000</pubDate>
    </item>
  </channel>
</rss>

