<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>Derick Rethans - tag: extensions</title>
    <link>http://derickrethans.nl/feed-extensions.xml</link>
    <description>This feed shows the latest 15 items with the tag extensions</description>
    <language>en-us</language>
    <copyright>All rights reserved - Derick Rethans</copyright>
    <managingEditor>derick@derickrethans.nl (Derick Rethans)</managingEditor>
    <pubDate>Tue, 13 Dec 2011 10:24:05 +0000</pubDate>
    <lastBuildDate>Tue, 13 Dec 2011 10:24: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>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>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>Valgrinding shared modules</title>
      <link>http://derickrethans.nl/valgrinding-shared-modules.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="valgrinding_shared_modules"/&gt;Valgrinding shared modules&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, August 8th 2011, 09:56 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Over the past year I've been writing various &lt;a href="http://derickrethans.nl/available-for-php-extension-writing.html"&gt;commercial&lt;/a&gt; (more about that later) and open source PHP extensions (such as &lt;a href="https://github.com/derickr/quickhash"&gt;QuickHash&lt;/a&gt;, more about that later too). Most of the time they are shared extensions that are not part of PHP. While testing whether I correctly free all memory with &lt;a href="http://valgrind.org/"&gt;Valgrind&lt;/a&gt;, I ran into the issue where I couldn't see the stack frames of where the memory leaks occurred in the extensions, and once I even ran into a &lt;a href="https://bugs.kde.org/show_bug.cgi?id=277045"&gt;Valgrind bug&lt;/a&gt;. The reason why Valgrind could not show the function names belonging to the stack frames is because PHP had already unloaded the shared extensions from memory.&lt;/p&gt;
      &lt;p&gt;I often found myself compiling the extensions into PHP statically so that there was nothing to unload for PHP, but that was becoming annoying. So instead I added a &lt;a href="http://news.php.net/php.cvs/65492"&gt;patch&lt;/a&gt; to PHP that prevents the shutdown sequence from actually unloading the modules. You can trigger this behaviour by setting the &lt;code&gt;ZEND_DONT_UNLOAD_MODULES&lt;/code&gt; environment variable before running your script:&lt;/p&gt;
      &lt;pre&gt;# export ZEND_DONT_UNLOAD_MODULES=1
# valgrind --leak-check=full --show-reachable=yes php -r 'echo "Hello World\n";'

&lt;/pre&gt;
      &lt;p&gt;Without &lt;code&gt;ZEND_DONT_UNLOAD_MODULES&lt;/code&gt; exported, my Valgrind output shows a block like:&lt;/p&gt;
      &lt;pre&gt;# unset ZEND_DONT_UNLOAD_MODULES
# valgrind --leak-check=full --show-reachable=yes php -r 'echo "Hello World\n";'
...
==25829== 8 bytes in 1 blocks are indirectly lost in loss record 2 of 21
==25829==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25829==    by 0xCE440DC: ???
==25829==    by 0xCE44316: ???
==25829==    by 0xCE44368: ???
==25829==    by 0xCBEE55F: ???
==25829==    by 0xCBD3F87: ???
==25829==    by 0x949A85: zend_activate_modules (zend_API.c:2285)
==25829==    by 0x8B5EBC: php_request_startup (main.c:1491)
==25829==    by 0xA83D60: do_cli (php_cli.c:954)
==25829==    by 0xA84F7B: main (php_cli.c:1356)
...

&lt;/pre&gt;
      &lt;p&gt;And with &lt;code&gt;ZEND_DONT_UNLOAD_MODULES&lt;/code&gt; exported, it shows instead:&lt;/p&gt;
      &lt;pre&gt;# export ZEND_DONT_UNLOAD_MODULES=1
# valgrind --leak-check=full --show-reachable=yes php -r 'echo "Hello World\n";'
...
==25824== 8 bytes in 1 blocks are still reachable in loss record 2 of 30
==25824==    at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25824==    by 0xCE440DC: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3)
==25824==    by 0xCE44316: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==25824==    by 0xCE44368: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==25824==    by 0xCBEE55F: zm_activate_http_request_pool (http_request_pool_api.c:58)
==25824==    by 0xCBD3F87: zm_activate_http (http.c:373)
==25824==    by 0x949A85: zend_activate_modules (zend_API.c:2285)
==25824==    by 0x8B5EBC: php_request_startup (main.c:1491)
==25824==    by 0xA83D60: do_cli (php_cli.c:954)
==25824==    by 0xA84F7B: main (php_cli.c:1356)
...

&lt;/pre&gt;
      &lt;p&gt;As you can see all the symbols are now nicely resolved. This patch is part of the upcoming PHP 5.4, but applies to &lt;a href="http://derickrethans.nl/files/php-zend-unload-modules-20110808.diff.txt"&gt;PHP 5.2 and PHP 5.3&lt;/a&gt; as well.&lt;/p&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201108080956</guid>
      <pubDate>Mon, 08 Aug 2011 08:56:00 +0000</pubDate>
    </item>
    <item>
      <title>Autumn Conferences</title>
      <link>http://derickrethans.nl/autumn-conferences.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="autumn_conferences"/&gt;Autumn Conferences&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, September 22nd 2010, 21:14 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;img src="http://derickrethans.nl/images/content/map-autumn2010.png" alt="map-autumn2010.png"/&gt;
      &lt;p&gt;Autumn started yesterday, and that also marks the start of the 2010 autumn conference schedule. In the next two and a half months I'll be attending and speaking at several conferences. Besides some of the older topics (PHP's date/time extension, and &lt;a href="http://xdebug.org"&gt;Xdebug&lt;/a&gt;) I will also give a few presentations on "Geolocation and Maps with PHP".&lt;/p&gt;
      &lt;p&gt;The new presentation covers the use of geolocation information with PHP. I will start with a theoretical background of all the services, mapping systems etc involved. After that, I will discuss on how to use geo-services from PHP. From obtaining of geo-location information through databases and services, mapping services to visualize geo-aware data to geo-aware data storage, manipulation and querying.&lt;/p&gt;
      &lt;p&gt;The talks are:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;p&gt;Debugging with &lt;a href="http://xdebug.org"&gt;Xdebug&lt;/a&gt; (&lt;a href="http://webexpo.net"&gt;WebExpo&lt;/a&gt;, Prague, September 24th)&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Geolocation and Maps with PHP (&lt;a href="http://conference.phpnw.org.uk/phpnw10/"&gt;PHP NorthWest&lt;/a&gt;, Manchester, October 9th)&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;PHP Inside (&lt;a href="http://phpconference.com/"&gt;IPC&lt;/a&gt;, Mainz, October 12th)&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Geolocation and Maps with PHP (IPC, Mainz, October 13th)&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Advanced Date/Time handling with PHP (&lt;a href="http://zendcon.com/"&gt;ZendCon&lt;/a&gt;, San Jose, November 2nd)&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Haystacks and Needles (&lt;a href="http://afup.org/pages/forumphp2010/"&gt;Forum PHP&lt;/a&gt;, Paris, November 10th)&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Geolocation and Maps with PHP (&lt;a href="http://afup.org/pages/forumphp2010/"&gt;Forum PHP&lt;/a&gt;, Paris, November 10th)&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;I am looking forwards to meeting all my old friends, and hoping to meet some new ones too. Come and say hello!&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>201009222114</guid>
      <pubDate>Wed, 22 Sep 2010 20:14:00 +0000</pubDate>
    </item>
    <item>
      <title>64-bit integers in MongoDB</title>
      <link>http://derickrethans.nl/64bit-ints-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="id_64-bit_integers_in_mongodb"/&gt;64-bit integers in MongoDB&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, August 9th 2010, 14:23 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;The current project that I'm working on relies heavily on &lt;a href="http://mongodb.org"&gt;MongoDB&lt;/a&gt;, a bridge between key-value stores and traditional RDBMS systems. Users in this project are identified by their Facebook &lt;a href="http://wiki.developers.facebook.com/index.php/User_ID"&gt;UserID&lt;/a&gt;, which is a "64-bit int datatype". Unfortunately, the &lt;a href="http://github.com/mongodb/mongo-php-driver"&gt;MongoDB PHP Driver&lt;/a&gt; only had support for 32-bit integers causing problems for newer users of Facebook. For those users, their nice long UserID was truncated to only 32 bits which didn't quite make the application work.&lt;/p&gt;
      &lt;p&gt;MongoDB stores documents internally in something called &lt;a href="http://bsonspec.org/"&gt;BSON&lt;/a&gt; (Binary &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt;). BSON has two integer types, a 32-bit signed integer type called &lt;code&gt;INT&lt;/code&gt; and a 64-bit signed integer type called &lt;code&gt;LONG&lt;/code&gt;. The documentation of the MongoDB PHP driver on &lt;a href="http://uk2.php.net/manual/en/mongo.types.php"&gt;types&lt;/a&gt; says (or used to say, depending on when you're reading this) that only the 32-bit signed integer type is supported because "PHP does not support 8 byte integers". That's not quite true. PHP's integer type supports 64-bit on the platforms where the C-data type &lt;code&gt;long&lt;/code&gt; is 64 bits. That is generally on every 64-bit platform (where PHP is compiled for 64 bits); except on Windows, where the C-data type &lt;code&gt;long&lt;/code&gt; is always only 32 bits.&lt;/p&gt;
      &lt;p&gt;Whenever a PHP integer is sent to MongoDB, the driver would use the 32 least significant bits to store the number as part of the document. The example here shows what happens (on a 64-bit platform):&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$m = new Mongo();
$c = $m-&gt;selectCollection('test', 'inttest');
$c-&gt;remove(array());

$c-&gt;insert(array('number' =&gt; 1234567890123456));

$r = $c-&gt;findOne();
echo $r['number'], "\n";
?&gt;

&lt;/pre&gt;
      &lt;p&gt;shows:&lt;/p&gt;
      &lt;pre&gt;int(1015724736)

&lt;/pre&gt;
      &lt;p&gt;In binary:&lt;/p&gt;
      &lt;pre&gt;1234567890123456 = 100011000101101010100111100100010101011101011000000
      1015724736 =                      111100100010101011101011000000

&lt;/pre&gt;
      &lt;p&gt;Truncating data is obviously not a very good idea. In order to address this issue we could just allow for the native PHP integer type to be used when storing data from PHP into MongoDB. But instead of changing how the MongoDB driver works by default I've added the new setting &lt;code&gt;mongo.native_long&lt;/code&gt; — simply because otherwise we might be breaking applications. With the &lt;code&gt;mongo.native_long&lt;/code&gt; setting enabled, we see the following result instead of the outcome of the script above:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
ini_set('mongo.native_long', 1);
$c-&gt;insert(array('number' =&gt; 1234567890123456));

$r = $c-&gt;findOne();
var_dump($r['number']);
?&gt;

&lt;/pre&gt;
      &lt;p&gt;This script shows:&lt;/p&gt;
      &lt;pre&gt;int(1234567890123456)

&lt;/pre&gt;
      &lt;p&gt;On &lt;strong&gt;64-bit platforms&lt;/strong&gt;, the &lt;code&gt;mongo.native_long&lt;/code&gt; setting allows for 64-bit integers to be stored in MongoDB. The MongoDB data type that is used in this case is the BSON LONG, instead of the BSON INT that is used if this setting is turned off. The setting &lt;em&gt;also&lt;/em&gt; changes the way how BSON LONGs behave when they are read back from MongoDB. Without &lt;code&gt;mongo.native_long&lt;/code&gt; enabled, the driver would convert every BSON LONG to a PHP double which results in the loss of precision. You can see that in the following example:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
ini_set('mongo.native_long', 1);
$c-&gt;insert(array('number' =&gt; 12345678901234567));

ini_set('mongo.native_long', 0);
$r = $c-&gt;findOne();
var_dump($r['number']);
?&gt;

&lt;/pre&gt;
      &lt;p&gt;This script shows:&lt;/p&gt;
      &lt;pre&gt;float(1.2345678901235E+16)

&lt;/pre&gt;
      &lt;p&gt;On &lt;strong&gt;32-bit platforms&lt;/strong&gt;, the &lt;code&gt;mongo.native_log&lt;/code&gt; setting changes nothing for storing integers in MongoDB: the integer is stored as a BSON INT as before. However, when the setting is enabled and a BSON LONG is read from MongoDB a &lt;a href="http://uk2.php.net/manual/en/class.mongocursorexception.php"&gt;MongoCursorException&lt;/a&gt; is thrown alerting you that the data could not be read back without losing precision:&lt;/p&gt;
      &lt;pre&gt;MongoCursorException: Can not natively represent the long 1234567890123456 on this platform

&lt;/pre&gt;
      &lt;p&gt;If the setting is not enabled, a BSON LONG is converted to a PHP float in order to avoid breaking backwards compatibility with the current behaviour.&lt;/p&gt;
      &lt;p&gt;Although the &lt;code&gt;mongo.native_long&lt;/code&gt; settings allows for 64-bit support on 64-bit platforms, it doesn't provide much for 32-bit platforms except preventing loss of precision while reading BSON LONGs—and then by just throwing an exception.&lt;/p&gt;
      &lt;p&gt;As part of making 64-bit integers work reliably with MongoDB, I've also added two new classes: &lt;code&gt;MongoInt32&lt;/code&gt; and &lt;code&gt;MongoInt64&lt;/code&gt;. These two classes are simple wrappers around a string representation of a number. They are instantiated like this:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$int32 = new MongoInt32("32091231");
$int64 = new MongoInt64("1234567980123456");
?&gt;

&lt;/pre&gt;
      &lt;p&gt;You can use those objects in normal insert and update queries just like normal numbers:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$m = new Mongo();
$c = $m-&gt;selectCollection('test', 'inttest');
$c-&gt;remove(array());

$c-&gt;insert(array(
        'int32' =&gt; new MongoInt32("1234567890"),
        'int64' =&gt; new MongoInt64("12345678901234567"),
));

$r = $c-&gt;findOne();
var_dump($r['int32']);
var_dump($r['int64']);
?&gt;

&lt;/pre&gt;
      &lt;p&gt;Which shows:&lt;/p&gt;
      &lt;pre&gt;int(1234567890)
float(1.2345678901235E+16)

&lt;/pre&gt;
      &lt;p&gt;As you can see, nothing is changed with how values are returned. A BSON INT is still returned as an integer, and a BSON LONG as a double. If we turn on the &lt;code&gt;mongo.native_long&lt;/code&gt; setting then the BSON LONG that was stored through the &lt;code&gt;MongoInt64&lt;/code&gt; class is returned as a PHP integer on 64-bit platforms, and a MongoCursorException is thrown on 32-bit platforms.&lt;/p&gt;
      &lt;p&gt;In order to received 64-bit integers back from MongoDB on 32-bit platforms, I've added another setting: &lt;code&gt;mongo.long_as_object&lt;/code&gt;. This will (on any platform) return a BSON LONG as stored in MongoDB as a &lt;code&gt;MongoInt64&lt;/code&gt; object. The following script demonstrates that:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$m = new Mongo();
$c = $m-&gt;selectCollection('test', 'inttest');
$c-&gt;remove(array());

$c-&gt;insert(array(
        'int64' =&gt; new MongoInt64("12345678901234567"),
));

ini_set('mongo.long_as_object', 1);
$r = $c-&gt;findOne();
var_dump($r['int64']);
echo $r['int64'], "\n";
echo $r['int64']-&gt;value, "\n";
?&gt;

&lt;/pre&gt;
      &lt;p&gt;This script outputs:&lt;/p&gt;
      &lt;pre&gt;object(MongoInt64)#7 (1) {
  ["value"]=&gt;
  string(17) "12345678901234567"
}
12345678901234567
12345678901234567

&lt;/pre&gt;
      &lt;p&gt;The &lt;code&gt;MongoInt32&lt;/code&gt; and &lt;code&gt;MongoInt64&lt;/code&gt; classes implement &lt;code&gt;__toString()&lt;/code&gt; so that their values can be echoed. You can only get their values out as strings. Please be aware that MongoDB is type-sensitive, and will not treat a number contained in a string the same way as a number that's just a number. This script shows this (on a 64-bit platform):&lt;/p&gt;
      &lt;pre&gt;&lt;?php
ini_set('mongo.native_long', 1);

$m = new Mongo();
$c = $m-&gt;selectCollection('test', 'inttest');
$c-&gt;remove(array());

$nr = "12345678901234567";
$c-&gt;insert(array('int64' =&gt; new MongoInt64($nr)));

$r = $c-&gt;findOne(array('int64' =&gt; $nr)); // $nr is a string here
var_dump($r['int64']);
$r = $c-&gt;findOne(array('int64' =&gt; (int) $nr));
var_dump($r['int64']);
?&gt;

&lt;/pre&gt;
      &lt;p&gt;Which shows:&lt;/p&gt;
      &lt;pre&gt;NULL
int(12345678901234567)

&lt;/pre&gt;
      &lt;p&gt;The following tables summarises all the different conversions regarding integers, depending on which settings are enabled:&lt;/p&gt;
      &lt;p&gt;&lt;strong&gt;PHP to MongoDB on 32-bit systems&lt;/strong&gt;:&lt;/p&gt;
      &lt;table&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;td rowspan="2"&gt;
              &lt;p&gt;From PHP                    &lt;/p&gt;
            &lt;/td&gt;
            &lt;td colspan="2"&gt;
              &lt;p&gt;Stored in Mongo                         &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;native_long=0       &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;native_long=1      &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;1234567                     &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)        &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)       &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;123456789012                &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;FLOAT(123456789012) &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;FLOAT(123456789012)&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;MongoInt32("1234567")       &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)        &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)       &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;MongoInt64("123456789012")  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;LONG(123456789012)  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;LONG(123456789012) &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
      &lt;p&gt;&lt;strong&gt;PHP to MongoDB on 64-bit systems&lt;/strong&gt;:&lt;/p&gt;
      &lt;table&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;td rowspan="2"&gt;
              &lt;p&gt;From PHP                    &lt;/p&gt;
            &lt;/td&gt;
            &lt;td colspan="2"&gt;
              &lt;p&gt;Stored in Mongo                         &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;native_long=0       &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;native_long=1      &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;1234567                     &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)        &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;LONG(1234567)      &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;123456789012                &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;&lt;em&gt;garbage&lt;/em&gt;           &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;LONG(123456789012) &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;MongoInt32("1234567")       &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)        &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)       &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;MongoInt64("123456789012")  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;LONG(123456789012)  &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;LONG(123456789012) &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
      &lt;p&gt;&lt;strong&gt;Mongo to PHP on 32-bit systems&lt;/strong&gt;:&lt;/p&gt;
      &lt;table&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;td rowspan="3"&gt;
              &lt;p&gt;Stored in Mongo   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td colspan="3"&gt;
              &lt;p&gt;Returned to PHP as                                                     &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td colspan="2"&gt;
              &lt;p&gt;long_as_object=0 &lt;/p&gt;
            &lt;/td&gt;
            &lt;td rowspan="2"&gt;
              &lt;p&gt;long_as_object=1         &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;native_long=0          &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;native_long=1       &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)      &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;int(1234567)           &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;int(1234567)        &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;int(1234567)              &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;LONG(123456789012)&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;float(123456789012)    &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;MongoCursorException&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;MongoInt64("123456789012")&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
      &lt;p&gt;&lt;strong&gt;Mongo to PHP on 64-bit systems&lt;/strong&gt;:&lt;/p&gt;
      &lt;table&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;td rowspan="3"&gt;
              &lt;p&gt;Stored in Mongo   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td colspan="3"&gt;
              &lt;p&gt;Returned to PHP as                                                     &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td colspan="2"&gt;
              &lt;p&gt;long_as_object=0 &lt;/p&gt;
            &lt;/td&gt;
            &lt;td rowspan="2"&gt;
              &lt;p&gt;long_as_object=1         &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;native_long=0          &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;native_long=1       &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;INT(1234567)      &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;int(1234567)           &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;int(1234567)        &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;int(1234567)              &lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;
              &lt;p&gt;LONG(123456789012)&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;float(123456789012)    &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;int(123456789012)   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;MongoInt64("123456789012")&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
      &lt;p&gt;
        &lt;strong&gt;Conclusion&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;Getting 64-bit support right with MongoDB can be tricky as we've seen. My recommendations would be to use just &lt;code&gt;mongo.native_long=1&lt;/code&gt; if you only deal with 64-bit platforms for your code. In this case, every integer number that you put into MongoDB will also come out as an integer number; with 64-bit integers supported.&lt;/p&gt;
      &lt;p&gt;If you however have to deal with 32-bit platforms (remember, that includes a 64-bit Windows build of PHP) then you can not reliably use just PHP's integer types and you &lt;strong&gt;have&lt;/strong&gt; to use the &lt;code&gt;MongoInt64&lt;/code&gt; class. This comes with the restriction that you have to deal with numbers in strings for initialisation. You also need to be aware that the MongoDB shell regards all numbers as floating point numbers, and that it can not represent 64-bit integer values. Instead they will show up as floating point numbers. Do &lt;strong&gt;not&lt;/strong&gt; attempt to modify those numbers on the shell, as that &lt;a href="http://www.mongodb.org/display/DOCS/mongo+-+The+Interactive+Shell#mongo-TheInteractiveShell-Numbers"&gt;could&lt;/a&gt; change the type.&lt;/p&gt;
      &lt;p&gt;So with the script:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$m = new Mongo();
$c = $m-&gt;selectCollection('test', 'inttest');
$c-&gt;remove(array());

$c-&gt;insert(array('int64' =&gt; new MongoInt64("123456789012345678")));

&lt;/pre&gt;
      &lt;p&gt;The MongoDB shell &lt;code&gt;mongo&lt;/code&gt; behaves like:&lt;/p&gt;
      &lt;pre&gt;$ mongo
MongoDB shell version: 1.4.4
url: test
connecting to: test
type "help" for help
&gt; use test
switched to db test
&gt; db.inttest.find()
{ "_id" : ObjectId("4c5ea6d59a14ce1319000000"), "int64" : { "floatApprox" : 123456789012345680, "top" : 28744523, "bottom" : 2788225870 } }

&lt;/pre&gt;
      &lt;p&gt;Of course, when fetching data through a driver that supports 64-bit integers you get the proper result:&lt;/p&gt;
      &lt;pre&gt;ini_set('mongo.long_as_object', 1);
$r = $c-&gt;findOne();
var_dump($r['int64']);
?&gt;

&lt;/pre&gt;
      &lt;p&gt;Which shows:&lt;/p&gt;
      &lt;pre&gt;object(MongoInt64)#7 (1) {
  ["value"]=&gt;
  string(18) "123456789012345678"
}

&lt;/pre&gt;
      &lt;p&gt;The new functionality as outlined in this article is part of the &lt;a href="http://pecl.php.net/package-info.php?package=mongo&amp;version=1.0.9"&gt;1.0.9 mongo release&lt;/a&gt; that's available through PECL with &lt;code&gt;pecl install mongo&lt;/code&gt;. Good luck with your 64-bit integers!&lt;/p&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201008091423</guid>
      <pubDate>Mon, 09 Aug 2010 13:23:00 +0000</pubDate>
    </item>
    <item>
      <title>Xdebug 2.1</title>
      <link>http://derickrethans.nl/xdebug-2.1-released.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_2_1"/&gt;Xdebug 2.1&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, June 29th 2010, 15:17 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;img src="http://derickrethans.nl/images/content/xdebug_logo.png" class="right" alt="xdebug_logo.png"/&gt;
      &lt;p&gt;I've just released &lt;a href="http://xdebug.org"&gt;Xdebug&lt;/a&gt; 2.1. This new release contains all the bug fixes and new features that have been developed over the past three years. It provides full PHP 5.3 support, but it no longer supports PHP versions below 5.1.&lt;/p&gt;
      &lt;p&gt;A description of all the new features follows:&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Error Collection&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;I've added xdebug_start_error_collection(), xdebug_stop_error_collection() and xdebug_get_collected_errors(), which allow you to collect all notices, warnings and error messages that Xdebug generates from PHP's error_reporting functionality so that you can output them at a later point in your script by hand.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Header Setting Interception&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;All functions that set HTTP headers such as with &lt;a href="http://php.net/header"&gt;header()&lt;/a&gt; and &lt;a href="http://php.net/setcookie"&gt;setcookie()&lt;/a&gt; are now intercepted by Xdebug. The intercepted headers are stored internally in an array that can be retrieved by calling the &lt;a href="http://xdebug.org/docs/all_functions#xdebug_get_headers"&gt;xdebug_get_headers()&lt;/a&gt; function. This is very useful in cases where you need to test certain functionality that sets headers somewhere deep in code. This function is also used in &lt;a href="http://ezcomponents.org"&gt;eZ Components'&lt;/a&gt; test suite to &lt;a href="http://svn.ez.no/svn/ezcomponents/trunk/MvcTools/tests/response_writers/http.php"&gt;test&lt;/a&gt; whether the correct HTTP headers are set in the &lt;a href="http://ezcomponents.org/s/MvcTools"&gt;MvcTools&lt;/a&gt; component.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Variable Assignment Tracing&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;The new setting &lt;a href="http://xdebug.org/docs/all_settings#collect_assignments"&gt;xdebug.collect_assignments&lt;/a&gt; allows you to record changes to variables in scripts to &lt;a href="http://xdebug.org/docs/execution_trace"&gt;trace files&lt;/a&gt;.  I've already written more about it in &lt;a href="http://derickrethans.nl/variable-tracing-with-xdebug.html"&gt;Variable tracing with Xdebug&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;"Scream" Support&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;The &lt;a href="http://pecl.php.net/scream"&gt;scream&lt;/a&gt; PECL extension disables the &lt;code&gt;@&lt;/code&gt; (shut-up) operator to actually see all notices, warnings and errors that PHP generates. The scream extension's functionality have been duplicated as Xdebug's &lt;a href="http://xdebug.org/docs/all_settings#scream"&gt;xdebug.scream&lt;/a&gt; php.ini setting. Why disabling the @-operator is a good thing, I've already outlined in &lt;a href="http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html"&gt;Five reasons why the shut-op operator (@) should be avoided&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Additions for Stack Traces&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;All HTML containers generated by Xdebug (error messages, &lt;a href="http://xdebug.org/docs/all_functions#xdebug_var_dump"&gt;xdebug_var_dump()&lt;/a&gt; output) now contain a CSS class for easier styling.&lt;/p&gt;
      &lt;p&gt;The new setting &lt;a href="http://xdebug.org/docs/all_settings#file_link_format"&gt;xdebug.file_link_format&lt;/a&gt; allows you to turn any file/line link in Xdebug's output to be decorated to a link with a specific format.  For example you can set it to &lt;code&gt;txmt://open/?file://%f&amp;line=%l&lt;/code&gt; for opening files directly in Textmate, or &lt;code&gt;gvim://%f@%l&lt;/code&gt; with some shell script for gvim and Firefox.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Remote Debugging&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;The new setting &lt;a href="http://xdebug.org/docs/all_settings#remote_connect_back"&gt;xdebug.remote_connect_back&lt;/a&gt;, contributed by Lucas Nealan and Brian Shire, allows Xdebug to try to make a debugging connection to the IP address from which the browser request came from. This setting is an additional solution for &lt;a href="http://derickrethans.nl/debugging-with-multiple-users.html"&gt;debugging with multiple users&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;The old &lt;code&gt;gdb&lt;/code&gt; and &lt;code&gt;php3&lt;/code&gt; remote debugging engines have been removed.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Overloaded var_dump&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;The newly introduced setting xdebug.overload_var_dump can be used to turn off Xdebug's default behavior of overriding PHP's &lt;a href="http://php.net/var_dump"&gt;var_dump()&lt;/a&gt; function with the &lt;a href="http://xdebug.org/docs/all_functions#xdebug_var_dump"&gt;xdebug_var_dump()&lt;/a&gt; function that uses pretty HTML for formatting a variable structure. It does not stop &lt;a href="http://xdebug.org/docs/all_functions#xdebug_var_dump"&gt;xdebug_var_dump()&lt;/a&gt; from working however.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Donations&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;You can probably imagine that writing and support Xdebug is a time-consuming effort. It's a tool that saves a lot of work during developement of applications, as well while debugging.  If you think Xdebug is valuable for you, perhaps you would like to consider a &lt;a href="http://xdebug.org/donate.php"&gt;donation&lt;/a&gt;. All donations are greatly appreciated and support future development and availablity of Xdebug.&lt;/p&gt;
      &lt;p&gt;If you want to sponsor a (new) feature in Xdebug, feel free to &lt;a href="mailto:derick@xdebug.org"&gt;contact&lt;/a&gt; me as well.&lt;/p&gt;
      &lt;p&gt;
        &lt;strong&gt;Download and Support&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;The new version of Xdebug can be downloaded through the &lt;a href="http://xdebug.org/download.php"&gt;download&lt;/a&gt; page. A list with all changes can be found on the &lt;a href="http://xdebug.org/updates.php#x_2_1_0"&gt;updates&lt;/a&gt; page. Support information can be found on the &lt;a href="http://xdebug.org/support.php"&gt;support&lt;/a&gt; page, and issues and feature requests can be filed in the &lt;a href="http://bugs.xdebug.org"&gt;bug tracker&lt;/a&gt;. Before asking for support, please have a look at the &lt;a href="http://xdebug.org/docs/faq"&gt;FAQ&lt;/a&gt; first.&lt;/p&gt;
      
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201006291449</guid>
      <pubDate>Tue, 29 Jun 2010 14:17:00 +0000</pubDate>
    </item>
    <item>
      <title>Find my Xdebug download wizard</title>
      <link>http://derickrethans.nl/find-my-xdebug-download-wizard.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="find_my_xdebug_download_wizard"/&gt;Find my Xdebug download wizard&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, May 3rd 2010, 10:00 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Installing &lt;a href="http://xdebug.org"&gt;Xdebug&lt;/a&gt; seems to be a problem for some users. The main trouble is for Windows users that don't know which file to download. Over the past few days I've worked on a &lt;a href="http://xdebug.org/find-binary.php"&gt;wizard&lt;/a&gt; that analyses &lt;a href="http://php.net/phpinfo"&gt;phpinfo()'s&lt;/a&gt; output and for Windows users suggests:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;p&gt;which file to download&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;where to put the file&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;which php.ini file to modify, and how&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;For Unix users, it explains:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;p&gt;which source tarball to download&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;how to compile&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;which php.ini file to modify, and how&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;I hope this makes it a bit easier to get going with Xdebug. Next up (hopefully this week) is release candidate 2 for Xdebug 2.1.0.&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201005031000</guid>
      <pubDate>Mon, 03 May 2010 09:00:00 +0000</pubDate>
    </item>
    <item>
      <title>PHP and Ordnance Survey Mapping</title>
      <link>http://derickrethans.nl/php-mapping.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="php_and_ordnance_survey_mapping"/&gt;PHP and Ordnance Survey Mapping&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, April 27th 2010, 14:27 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;About a month ago, &lt;a href="http://www.ordnancesurvey.co.uk/"&gt;Ordnance Survey&lt;/a&gt; &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/media/news/2010/April/OpenData.html"&gt;opened&lt;/a&gt; up some of their data for public consumption under a brand called &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/opendata/"&gt;OpenData&lt;/a&gt;. The data is &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/opendata/licence/docs/licence.pdf"&gt;licenced&lt;/a&gt; under a "Creative Commons Attribute"-like license. One of the data sets they provide is &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/products/code-point-open/"&gt;Code-Point Open&lt;/a&gt; and provides a dataset "that contains postcode units, each of which have a precise geographical location". I've always been a bit of a map-geek, and have always geotagged my &lt;a href="http://www.flickr.com/photos/derickrethans/map"&gt;pictures&lt;/a&gt; and some of my &lt;a href="http://twitter.com/derickr"&gt;tweets&lt;/a&gt;. So I was wondering what cool thing I could do with this newly released data.  I decided to map all the postcodes onto the UK map where more postcodes for a specific place would create a "lighter" colour. Each postcode has on average about 15 addresses, so in more densely populated areas you have more "postcodes-per-area". Doing this wasn't very difficult and it resulted in the following map:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/postcode-uk-scaled.jpg" alt="postcode-uk-scaled.jpg"/&gt;
      &lt;p&gt;You can very clearly see the more densely populated areas such as London.&lt;/p&gt;
      &lt;p&gt;This generated postcode-density map I wanted to overlay on a real map, such as OpenStreetMap provides. When I tried to align the image that I generated with the OSM map, I ended up with this:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/uk-osm-postcode-overlay.jpg" alt="uk-osm-postcode-overlay.jpg"/&gt;
      &lt;p&gt;Obviously, the maps don't align. In order to fix this, I ended up learning a lot more about map projections.&lt;/p&gt;
      &lt;p&gt;The &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/products/code-point-open/"&gt;Code-Point Open&lt;/a&gt; data uses the UK's &lt;a href="http://en.wikipedia.org/wiki/British_national_grid_reference_system#Grid_letters"&gt;National Grid&lt;/a&gt; to store location data in. The National Grid consists of 100*100 km squares that are then further subdivided into smaller squares creating grid references such as &lt;em&gt;TQ3012780512&lt;/em&gt;, or the numerical version &lt;em&gt;530128 180512&lt;/em&gt;. &lt;em&gt;TQ&lt;/em&gt; translates into the "hundred thousands" of the &lt;em&gt;Eastings&lt;/em&gt; and &lt;em&gt;Northings&lt;/em&gt; according to the grid that you can see &lt;a href="http://en.wikipedia.org/wiki/File:National_Grid_for_Great_Britain_with_central_meridian.gif"&gt;here&lt;/a&gt;. In this case, it specifies a point 530 128 meters East and 180 512 meters North of the origin.  (If you work it out, you'll end up in London).&lt;/p&gt;
      &lt;p&gt;&lt;a href="http://www.openstreetmap.org/"&gt;OpenStreetMap&lt;/a&gt; uses a &lt;a href="http://en.wikipedia.org/wiki/Mercator_projection"&gt;Mercator&lt;/a&gt; projection to visualize maps. The Mercator projection is a cylindrical map projection, and it distorts the size and shape of large objects, as the scale increases from the Equator to the poles. Therefore it only works from about 85°N to 85°S (why it is 85° only be came clear after doing all the maths for it). Google Maps uses the same projection.&lt;/p&gt;
      &lt;p&gt;There were a few challenges plotting the &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/products/code-point-open/"&gt;Code-Point Open&lt;/a&gt; data on an OpenStreetMap map:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          &lt;p&gt;The National Grid coordinates need to be converted to Latitude/Longitude pairs&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
          &lt;p&gt;Latitude/Longitude pairs need to be mapped to pixels to align with the Mercator projection of OpenStreetMap maps.&lt;/p&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;For &lt;strong&gt;converting National Grid&lt;/strong&gt; references to Latitude/Longitude pairs I found some &lt;a href="http://www.movable-type.co.uk/scripts/latlong-gridref.html"&gt;JavaScript code&lt;/a&gt;. I converted this code to PHP and to verify whether my code was working properly, I used &lt;a href="http://www.fieldenmaps.info/cconv/cconv_gb.html"&gt;this site&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;&lt;strong&gt;Converting Latitude/Longitude&lt;/strong&gt; pairs to the pixel coordinates of OSM required a bit of maths. OSM provides maps in different zoom levels, from &lt;a href="http://www.openstreetmap.org/?lat=0&amp;lon=0&amp;zoom=2&amp;layers=B000FTFT"&gt;2&lt;/a&gt; to &lt;a href="http://www.openstreetmap.org/?lat=51.500834&amp;lon=-0.142455&amp;zoom=17&amp;layers=B000FTFT"&gt;17&lt;/a&gt;. Each zoom level having twice the amount of pixels horizontally and vertically.  Zoom level 2 has 4 times 4 tiles, where each tile is 256*256 pixels. At zoom level two, the whole world fits into 1024*1024 pixels. The number of pixels for each axis for a specific zoom-level can be calculated by:&lt;/p&gt;
      &lt;pre&gt;pow(2^zoom) * 256

&lt;/pre&gt;
      &lt;p&gt;For a zoom level of 7 that makes 16384 pixels in each direction. To convert a longitude (in the range -180° to 180°) we can simply apply:&lt;/p&gt;
      &lt;pre&gt;x = ((lon + 180) / 360) * (pow(2^zoom) * 256)

&lt;/pre&gt;
      &lt;p&gt;For a Longitude of 0.003117° E at zoom-level 13 that turns out to be pixel 1048594.&lt;/p&gt;
      &lt;p&gt;Longitude conversions are more difficult due to the Mercator projection itself. To convert we apply:&lt;/p&gt;
      &lt;pre&gt;y = ((atanh(sin(deg2rad(-lat))) / π) + 1) * (pow(2^(zoom-1)))

&lt;/pre&gt;
      &lt;p&gt;For a Latitude of 51.502817° N at zoom-level 13 that turns out to be pixel 697399.&lt;/p&gt;
      &lt;p&gt;Creating an image for the whole world at zoom level 13 is impractical as it is 2097152*2097152 pixels and downloading all the 67 million tiles for this zoom level is probably not liked by the OSM people either. So instead we take a cut out for a specific area only. For the UK (61.37°N -9.49° W, 49.76°N +3.63°E) at zoom level 7 we end up with a 1536x2048 map with the North-Western pixel being 15360,9216. On this map, we can draw the latitudes and longitudes as well as the National Grid lines (full image is on &lt;a href="http://farm4.static.flickr.com/3001/4557130189_af995cab6b_o.png"&gt;flickr&lt;/a&gt;):&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/uk-osm-lines-crop.jpg" alt="uk-osm-lines-crop.jpg"/&gt;
      &lt;p&gt;The only thing left to do now, is to map the postcode density information to the map. I picked zoom level 6 for this, and the result is (after cropping it to 640 pixels width):&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/uk-osm-postcode.jpg" alt="uk-osm-postcode.jpg"/&gt;
      &lt;p&gt;As you can see, this is perfect fit to the outlines of the country. But unfortunately, when we look very closely at the plotted map data, for example for the &lt;em&gt;NW10 3&lt;/em&gt; postcodes, we notice that the mapping is slightly off. The blue dots are what we plotted, and the red dots are what the locations &lt;strong&gt;should&lt;/strong&gt; have been:&lt;/p&gt;
      &lt;img src="http://derickrethans.nl/images/content/uk-osm-nw103-1.png" alt="uk-osm-nw103-1.png"/&gt;
      &lt;p&gt;The reason for this is that when we converted the National Grid locations to Latitude/Longitude pairs to plot on the OSM maps, I forgot to take into account the different &lt;a href="http://en.wikipedia.org/wiki/Datum_%2528geodesy%2529"&gt;Datums&lt;/a&gt; that are used in the projections. The Earth is not a perfect sphere, and an approximation of the ellipsoid of the whole Earth is not necessarily the best fitting for a specific area such as the UK. Therefore, the National Grid uses the &lt;a href="http://en.wikipedia.org/wiki/OSGB36#Datum_shift_between_OSGB_36_and_WGS_84"&gt;OSGB36&lt;/a&gt; Datum which fits more closely to the UK, where as OpenStreetMap uses the WGS84 Datum that is also used by GPS. The &lt;a href="http://osi.ie/"&gt;Ordnance Survey Ireland&lt;/a&gt; has a more thorough &lt;a href="http://www.osi.ie/GetAttachment.aspx?id=b2bd07a6-858e-4eb1-9d09-25917f0c713a"&gt;explanation&lt;/a&gt; on their site. As you can see above, using the wrong Datum can mean locations can be off. In our example about 100 meters. Converting between different Datums is possible, albeit processor intensive.&lt;/p&gt;
      &lt;p&gt;After I figured out all the maths for this, the only problem that remains that implementing those algorithms in PHP is show—calculating all the positions from the 1.6 million postcode locations takes up to 10 minutes. This is why I am not presenting any code yet. I am planning to implement all the necessary calculations in a &lt;a href="http://derickrethans.nl/available-for-php-extension-writing.html"&gt;PHP extension&lt;/a&gt; to speed up the calculations&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201004271427</guid>
      <pubDate>Tue, 27 Apr 2010 13:27:00 +0000</pubDate>
    </item>
    <item>
      <title>VLD released</title>
      <link>http://derickrethans.nl/vld-released.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="vld_released"/&gt;VLD 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;Monday, April 12th 2010, 21:57 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I just released a new version of &lt;a href="http://derickrethans.nl/projects.html#vld"&gt;VLD&lt;/a&gt; through &lt;a href="http://pecl.php.net/package/vld"&gt;PECL&lt;/a&gt;. This release features the path analytics code that I've outlined in an &lt;a href="http://derickrethans.nl/more-source-analysis-with-vld.html"&gt;earlier article&lt;/a&gt;. There are also a few fixes for PHP's current trunk, as well as the possibility to format output slightly like a CSV file. That feature was used to make &lt;a href="http://www.zapt.info/opcodes.html"&gt;this&lt;/a&gt; documentation of opcodes.&lt;/p&gt;
      &lt;p&gt;The path analysis algorithm that &lt;a href="http://derickrethans.nl/projects.html#vld"&gt;VLD&lt;/a&gt; now has, can possibly also be used to get path/branch coverage working within &lt;a href="http://xdebug.org"&gt;Xdebug's&lt;/a&gt; code-coverage framework. This is however not a minor task.&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201004122157</guid>
      <pubDate>Mon, 12 Apr 2010 20:57:00 +0000</pubDate>
    </item>
    <item>
      <title>Xdebug 2.1.0 RC1 released</title>
      <link>http://derickrethans.nl/xdebug-2.1.0rc1-released.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_2_1_0_rc1_released"/&gt;Xdebug 2.1.0 RC1 released&lt;/h1&gt;
      &lt;dl class="head"/&gt;
      &lt;div class="articleMetaData"&gt;
        &lt;div class="location"&gt; Schiphol, Netherlands&lt;/div&gt;
        &lt;div class="date"&gt;Tuesday, April 6th 2010, 15:41 CEST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;As earlier announced in my April Fools' &lt;a href="http://derickrethans.nl/xdebug-will-cost-money.html"&gt;announcement&lt;/a&gt; and on Xdebug's &lt;a href="http://twitter.com/xdebug/status/11687180290"&gt;twitter&lt;/a&gt; feed, I'm now releasing &lt;a href="http://xdebug.org"&gt;Xdebug&lt;/a&gt; 2.1.0RC1. This is the first Release Candidate and it addresses a number of &lt;a href="http://xdebug.org/updates.php#x_2_1_0rc1"&gt;issues&lt;/a&gt; found in the latest beta. As I usually do in release announcements, I will also be introducing a new feature in Xdebug 2.1 in this one.&lt;/p&gt;
      &lt;p&gt;In an &lt;a href="http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html"&gt;article&lt;/a&gt; that I wrote a few months ago, I illustrated a few different reasons on why the shut-op operator (&lt;code&gt;@&lt;/code&gt;) should be avoided. Although there are a few cases where it simple can not be avoided if you want to write notice-free code, the main reason why this operator should be avoided, is because it makes debugging quite a bit more difficult if errors are hidden.&lt;/p&gt;
      &lt;p&gt;Xdebug is a debugging aid to make debugging easier. So from version 2.1.0 there is a new configuration setting — &lt;code&gt;xdebug.scream&lt;/code&gt; — that simply disables the effects of the &lt;code&gt;@&lt;/code&gt; operator. That means that all errors will be shown, of course, still listening to the &lt;code&gt;error_reporting&lt;/code&gt; and &lt;code&gt;display_errors&lt;/code&gt; settings. This functionality is not a novel thing, and the idea was lifted from the PECL &lt;a href="http://pecl.php.net/scream"&gt;scream&lt;/a&gt; package. However, I think this functionality fits in very well with all the other things that Xdebug has to offer.&lt;/p&gt;
      &lt;p&gt;Just to mention it once more, I have no intention of making Xdebug closed source. I spend a considerable amount of time in adding new features and addressing issues, so I would appreciate it that if consider a &lt;a href="http://xdebug.org/donate.php"&gt;donation&lt;/a&gt; in case Xdebug has saved you time and effort in debugging your application. If you have comments or suggestions to improve Xdebug, please write to the &lt;a href="http://xdebug.org/support.php#list"&gt;mailinglist&lt;/a&gt;.&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201004061541</guid>
      <pubDate>Tue, 06 Apr 2010 13:41:00 +0000</pubDate>
    </item>
    <item>
      <title>First release of the D-Bus extension</title>
      <link>http://derickrethans.nl/dbus-extension-released.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="first_release_of_the_d-bus_extension"/&gt;First release of the D-Bus 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;Tuesday, April 6th 2010, 10:33 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;A few days ago I made the first beta release of the &lt;a href="http://pecl.php.net/package/dbus"&gt;D-Bus extension&lt;/a&gt; that I have been working on for a while. &lt;a href="http://www.freedesktop.org/wiki/Software/dbus"&gt;D-Bus&lt;/a&gt; is a message bus system, a simple way for applications to talk to one another. I started working on this because my cellphone, an OpenMoko &lt;a href="http://www.openmoko.com/freerunner.html"&gt;FreeRunner&lt;/a&gt;. This cellphone (or rather, a mobile Linux computing device) implements &lt;a href="http://www.freesmartphone.org/"&gt;freesmartphone.org&lt;/a&gt; APIs to talk to all the hardware that is available on the device. This includes GSM and SIM card interfaces, but also GPS, Audio and PIM services.&lt;/p&gt;
      &lt;p&gt;However, many other applications on the Linux desktop speak D-Bus. This includes system services such as the notification daemon, the screen saver and hardware plug-in detection as well as desktop applications such as &lt;a href="http://www.pidgin.im/"&gt;Pidgin&lt;/a&gt; and &lt;a href="http://live.gnome.org/Empathya"&gt;Empathy&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;I've given a &lt;a href="http://derickrethans.nl/talks/dbus-london2010.pdf"&gt;presentation&lt;/a&gt; on the extension at the &lt;a href="http://www.phpconference.co.uk/"&gt;PHP London conference&lt;/a&gt; earlier this year, and will also be speaking on this subject as part of the "PHP Inside" and "PHP on the D-Bus" talks at &lt;a href="http://tek.phparch.com/schedule/"&gt;Tek-X&lt;/a&gt; (Chicago, May 18-21), &lt;a href="http://it-republik.de/php/phpconference2010se/"&gt;International PHP Conference Spring&lt;/a&gt; (Berlin, May 30-June 2) and the &lt;a href="http://phpconference.nl/"&gt;Dutch PHP Conference&lt;/a&gt; (June 10-12).&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201004060920</guid>
      <pubDate>Tue, 06 Apr 2010 09:33:00 +0000</pubDate>
    </item>
    <item>
      <title>Xdebug no longer Open Source</title>
      <link>http://derickrethans.nl/xdebug-will-cost-money.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_no_longer_open_source"/&gt;Xdebug no longer Open Source&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 1st 2010, 10:19 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;
        &lt;strong&gt;This was obviously an April Fools' joke, Xdebug will continue to stay Open Source and free of charge.&lt;/strong&gt;
      &lt;/p&gt;
      &lt;p&gt;Later today I will be releasing the first Release Candidate of Xdebug 2.1. With regret I have to announce that from this release, I will no longer provide Xdebug as an open source debugger extension. I've noticed that there are other projects making money of Xdebug's success while I only receive &lt;a href="http://xdebug.org/donate.php"&gt;donations&lt;/a&gt; from a group of awesome supporters.&lt;/p&gt;
      &lt;p&gt;Xdebug will continue to be available for benefactors on a limited number of platforms that I have access to (Linux 32/64bit and Windows). Please refer to the &lt;a href="http://derickrethans.nl/files/dump/faq.html"&gt;FAQ&lt;/a&gt; for further information.&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201004011019</guid>
      <pubDate>Thu, 01 Apr 2010 09:19:00 +0000</pubDate>
    </item>
    <item>
      <title>Storing Date/Times in Databases</title>
      <link>http://derickrethans.nl/storing-date-time-in-database.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="storing_date_times_in_databases"/&gt;Storing Date/Times in Databases&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, March 29th 2010, 16:47 BST&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;After my talk during &lt;a href="http://confoo.ca/en"&gt;ConFoo&lt;/a&gt; on &lt;a href="http://confoo.ca/en/2010/session/advanced-date-time-handling-with-php"&gt;Advanced Date/Time Handling&lt;/a&gt; I received a question about whether the UTC-offset, together with the date/time in years, months, days, hours, minutes and seconds, was enough for storing a date/time in a database and still being able to do calculations with this. The answer to this question was no, but it lead to an even more interesting discussion about what &lt;em&gt;would&lt;/em&gt; be enough to store an accurate date/time in a database.&lt;/p&gt;
      &lt;p&gt;Firstly let me explain why storing a UTC offset is not adequate at all for doing any sort of calculations. Right now (March 25th, 2010), Montreal is on the same time as Santiago (in Chile) with both a UTC offset of -4 hours. This means that for the same date/time (&lt;code&gt;2010-03-25
19:03&lt;/code&gt;) the same timestamp is generated (&lt;code&gt;1269558180&lt;/code&gt;). However if we want to add eight months (&lt;code&gt;2010-11-25 19:03&lt;/code&gt;) to the current time for each of those locations then the timestamps &lt;em&gt;should&lt;/em&gt; be different — &lt;code&gt;1290729780&lt;/code&gt; for Montreal and &lt;code&gt;1290722580&lt;/code&gt; for Santiago. It turns out that &lt;em&gt;neither&lt;/em&gt; of them is exactly a full 24 hour difference from &lt;code&gt;2010-03-25 19:03&lt;/code&gt; as is shown the following script:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$s = '2010-03-25 19:03';
$montrealNow = date_create( "{$s} America/Montreal" )-&gt;format( 'U' );
$santiagoNow = date_create( "{$s} America/Santiago" )-&gt;format( 'U' );
$s = '2010-11-25 19:03';
$montrealThen = date_create( "{$s} America/Montreal" )-&gt;format( 'U' );
$santiagoThen = date_create( "{$s} America/Santiago" )-&gt;format( 'U' );

$hour = 60 * 60;
$day = 24 * $hour;

echo "Montreal:\n",
    $montrealNow, " - ",
    $montrealThen, "\n",
    ( ( $montrealThen - $montrealNow ) % $day ) / $hour, "\n\n";

echo "Santiago:\n",
    $santiagoNow, " - ",
    $santiagoThen, "\n",
    ( ( $santiagoThen - $santiagoNow ) % $day ) / $hour, "\n\n";

?&gt;

&lt;/pre&gt;
      &lt;p&gt;which gives the output:&lt;/p&gt;
      &lt;pre&gt;Montreal:
1269558180 - 1290729780
1

Santiago:
1269558180 - 1290722580
23

&lt;/pre&gt;
      &lt;p&gt;From this we see that Montreal has an extra hour and Santiago has an hour less. This is because Montreal changed from Daylight Savings Time to normal time and Santiago, being on the southern hemisphere, moved from normal time to Daylight Savings time.&lt;/p&gt;
      &lt;p&gt;Now if we had only the timestamp (&lt;code&gt;1269558180&lt;/code&gt;) and the UTC-offset, the only thing we could do would be to advance a specific number of days. In this case, there are 245 days, which makes (&lt;code&gt;245 * 24 * 60 * 60 =&lt;/code&gt; ) &lt;code&gt;21168000&lt;/code&gt; seconds. If we add this to the original timestamp, we end up at &lt;code&gt;1290726180&lt;/code&gt; which corresponds to &lt;code&gt;2010-11-25 18:03&lt;/code&gt; Montreal time, or &lt;code&gt;2010-11-25 20:03&lt;/code&gt; Santiago time. Neither of them being the correct &lt;code&gt;2010-11-25 19:03&lt;/code&gt;. Because from the UTC offset of 4 hours we don't know whether we're in Montreal or Santiago, we can conclude that with just this UTC offset and the original timestamp we can't calculate the timestamp of something that's 8 months in the future. Storing the UTC-offset can not change this fact either.&lt;/p&gt;
      &lt;p&gt;In order to to proper calculations, you need to keep information about the timezone itself. In PHP timezones are identified with identifiers such as &lt;code&gt;America/Montreal&lt;/code&gt;. If we store those alongside the timestamps, we can do the proper calculations. The following example demonstrates that:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$timestamp = 1269558180;
$tzid      = 'America/Montreal';

$d = new DateTime( "@$timestamp" );
$d-&gt;setTimeZone( new DateTimeZone( $tzid ) );
$d-&gt;modify( '+8 months' );

echo $d-&gt;format( 'Y-m-d H:i' ), "\n";
?&gt;

&lt;/pre&gt;
      &lt;p&gt;which gives the output: &lt;code&gt;2010-11-25 19:03&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;This seems to work, but unfortunately, even the approach of storing the timestamp and timezone identifier is not going to work correctly under certain circumstances. In order to find out why, we have to go back to January this year.&lt;/p&gt;
      &lt;p&gt;Imagine that in January this year—January 15th to be precise—we run the following script to determine the timestamp of a date/time two months in the future:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$tz = 'America/Santiago';
$ts = date_create( "2010-01-15 10:41 $tz" )-&gt;format( 'U' );

$d = new DateTime( "@$ts" );
$d-&gt;setTimeZone( new DateTimeZone( $tz ) );
$d-&gt;modify( '+2 months' );

echo $d-&gt;format( 'U Y-m-d H:i' ), "\n";
?&gt;

&lt;/pre&gt;
      &lt;p&gt;This returns the timestamp &lt;code&gt;1268664060&lt;/code&gt; for the date/time &lt;code&gt;2010-03-15
10:41:00&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;Now skip forwards to the current date and time. If we used this calculated timestamp and the timezone identifier &lt;code&gt;America/Santiago&lt;/code&gt; today to generate a date/time string, we would however get a different output. The following example shows this:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$tz = 'America/Santiago';
$d = date_create( "@1268664060" );
$d-&gt;setTimeZone( new DateTimeZone( $tz ) );

echo $d-&gt;format( 'Y-m-d H:i:s' ), "\n";
?&gt;

&lt;/pre&gt;
      &lt;p&gt;which gives the output: &lt;code&gt;2010-03-15 11:41:00&lt;/code&gt; (and not &lt;code&gt;2010-03-15
10:41:00&lt;/code&gt;).&lt;/p&gt;
      &lt;p&gt;The difference in output is not a bug, but is caused because some countries change Daylight Savings Time rules quite frequently. In this case Chile decided (on March 4th) that instead of going forwards to DST at midnight March 14th, they will delay that to April 4th. When we ran the code on January 15th, the rules still thought that March 15th would already be on normal time again, outside of DST. But running the code now, with the updated rule set, we find that DST is still in effect until April 4th. The following example shows the transitions from/to DST for Santiago in 2010:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$tzid = "America/Santiago";

$tz = new DateTimeZone( $tzid );
$transitions = $tz-&gt;getTransitions(
    strtotime( '2010-01-01 00:00 UTC' ),
    strtotime( '2010-12-31 00:00 UTC' )
);

foreach ( $transitions as $t )
{
    echo $t['time'], ' ', $t['offset'] / 3600, ' ', $t['abbr'], "\n";
}
?&gt;

&lt;/pre&gt;
      &lt;p&gt;If we run this script with PHP 5.3.1 or 5.3.2—which still have the old incorrect rule set—the output is:&lt;/p&gt;
      &lt;pre&gt;2010-01-01T00:00:00+0000 -3 CLST
2010-03-14T03:00:00+0000 -4 CLT
2010-10-10T04:00:00+0000 -3 CLST

&lt;/pre&gt;
      &lt;p&gt;In the SVN repository, the rule set has been updated, so snapshots of PHP 5.3-dev have the correct rules and the script will show:&lt;/p&gt;
      &lt;pre&gt;2010-01-01T00:00:00+0000 -3 CLST
2010-04-04T03:00:00+0000 -4 CLT
2010-10-10T04:00:00+0000 -3 CLST

&lt;/pre&gt;
      &lt;p&gt;This leads to the conclusion that storing timestamps and timezone identifiers is not good enough either, unless you want an &lt;em&gt;exact&lt;/em&gt; point in time, as opposed to the more expected date/time in a location. So how &lt;em&gt;should&lt;/em&gt; you store the latter then? Basically, in the same way that DateTime objects are serialized in PHP 5.3. Let us imagine again, that the following code is run on January 15th again:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$tzid = 'America/Santiago';
$d = new DateTime( "2010-01-15 10:41 $tzid" );
$d-&gt;modify( '+2 months' );
$s = $d-&gt;format( 'Y-m-d H:i:s' );
$ts = $d-&gt;format( 'U' );
echo "$s (ts=$ts)\n";
?&gt;

&lt;/pre&gt;
      &lt;p&gt;which gives the output &lt;code&gt;2010-03-15 10:41:00 (ts=1268664060)&lt;/code&gt;. The next example is run with a recent rule set (such as in PHP SVN) today:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$tzid = 'America/Santiago';
$d = new DateTime( "$s $tzid" );
$s = $d-&gt;format( 'Y-m-d H:i:s' );
$ts = $d-&gt;format( 'U' );
echo "$s (ts=$ts)\n";
?&gt;

&lt;/pre&gt;
      &lt;p&gt;which gives the output &lt;code&gt;2010-03-15 10:41:00 (ts=1268660460)&lt;/code&gt;. As you can see, now the date/time itself is correct, although there is a different timestamp. PHP's DateTime serialisation does something similar:&lt;/p&gt;
      &lt;pre&gt;&lt;?php
$d = new DateTime();
$d-&gt;setTimeZone( new DateTimeZone( 'America/Santiago' ) );
var_dump( $d );
?&gt;

&lt;/pre&gt;
      &lt;p&gt;which gives the output:&lt;/p&gt;
      &lt;pre&gt;object(DateTime)#1 (3) {
  ["date"]=&gt;
  string(19) "2010-03-29 11:32:08"
  ["timezone_type"]=&gt;
  int(3)
  ["timezone"]=&gt;
  string(16) "America/Santiago"
}

&lt;/pre&gt;
      &lt;p&gt;For things to work correctly, you need to have an up-to-date rule set. PHP versions are not released as often as the timezonedb (sometimes more than 20 times a year) and to address this issue you can install the pecl extension &lt;a href="http://pecl.php.net/package/timezonedb"&gt;timezonedb&lt;/a&gt; with &lt;code&gt;pecl install timezonedb&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;To store information in a database, I would use a &lt;code&gt;char&lt;/code&gt; column-type to store the whole &lt;code&gt;America/Santiago&lt;/code&gt; timezone identifier and another &lt;code&gt;char&lt;/code&gt; column-type to store the date/time (in the &lt;code&gt;yyyy-mm-dd
hh:ii:ss&lt;/code&gt; format).  Alternatively, you can pick a 'datetime' column-type, as long as that type &lt;strong&gt;ignores&lt;/strong&gt; timezones altogether. For MySQL that is the &lt;code&gt;DATETIME&lt;/code&gt; column-type, and for PostgreSQL the &lt;code&gt;TIMESTAMP&lt;/code&gt; or &lt;code&gt;TIMESTAMP WITHOUT TIME ZONE&lt;/code&gt; column-types.&lt;/p&gt;
      &lt;p&gt;Databases rarely handle timezones, daylight savings time and rule changes correctly, so avoid the database specific functionality all together. Using either a &lt;code&gt;char&lt;/code&gt; or a timezone-less 'datetime' column-type would still allow you to sort and by using a 'datetime' column-type you can even do calculations.&lt;/p&gt;
      &lt;p&gt;Happy summer time!&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201003291647</guid>
      <pubDate>Mon, 29 Mar 2010 15:47:00 +0000</pubDate>
    </item>
    <item>
      <title>Available for PHP Extension Writing</title>
      <link>http://derickrethans.nl/available-for-php-extension-writing.html</link>
      <description>&lt;div class="article"&gt;
  &lt;div class="body"&gt;
    &lt;div class="articleListItem"&gt;
      &lt;h1&gt;&lt;a name="available_for_php_extension_writing"/&gt;Available for PHP Extension Writing&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, March 15th 2010, 12:28 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;Slightly more than a month ago I left my job as team-lead of &lt;a href="http://ezcomponents.org"&gt;eZ Components&lt;/a&gt; at &lt;a href="http://ez.no"&gt;eZ Systems&lt;/a&gt; behind, to focus on something new. During the past month I've been contemplating about what to do next and realized that I do not want to take on a new full-time position right away.  Instead I will be available to work on (custom) PHP extensions and internals related issues. Extensions are a great way around PHP's limitations and performance issues.&lt;/p&gt;
      &lt;p&gt;As first project I am working on a "&lt;a href="https://github.com/derickr/quickhash"&gt;QuickHash&lt;/a&gt;" extension for &lt;a href="http://www.stumbleupon.com/"&gt;StumbleUpon&lt;/a&gt;. This extension circumvents PHP's hefty memory (and performance) overhead by providing more specific data structures. The extension currently implements integer sets and integer to integer hashes. I am now adding integer to string hashes and string to integer hashes. The QuickHash extension will be released under the PHP Licence and I will dedicate another post to it later.&lt;/p&gt;
      &lt;p&gt;If, like &lt;a href="http://www.stumbleupon.com/"&gt;StumbleUpon&lt;/a&gt;, you are also interested in having work done on PHP or a specific extensions feel free to &lt;a href="http://derickrethans.nl/who.html"&gt;contact&lt;/a&gt; me. I'd be happy to discuss things with you.&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201003151228</guid>
      <pubDate>Mon, 15 Mar 2010 12:28:00 +0000</pubDate>
    </item>
    <item>
      <title>Xdebug 2.1.0beta3 released</title>
      <link>http://derickrethans.nl/xdebug-210beta3.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_2_1_0beta3_released"/&gt;Xdebug 2.1.0beta3 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;Saturday, February 27th 2010, 23:57 GMT&lt;/div&gt;
      &lt;/div&gt;
      &lt;p&gt;I've just released Xdebug 2.1.0beta3 which includes a few crash bugs as well as the issue that headers sent from PHP scripts are not actually set.&lt;/p&gt;
      &lt;p&gt;You can find the full changelog &lt;a href="http://xdebug.org/updates.php#x_2_1_0beta3"&gt;here&lt;/a&gt; and get the latest version from the &lt;a href="http://xdebug.org/download.php"&gt;download page&lt;/a&gt;.&lt;/p&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</description>
      <guid>201002272352</guid>
      <pubDate>Sat, 27 Feb 2010 23:57:00 +0000</pubDate>
    </item>
  </channel>
</rss>

