Xdebug 2.3: Moar var_dump()

This is the first article in a series about the new features in Xdebug 2.3, which was first released on February 22nd.

One of the new features relates to one of the first things that I added in the original Xdebug: making the var_dump() output "pretty". Xdebug replaces PHP's standard var_dump() function with its own version, as long as the xdebug.overload_var_dump setting is not set to 0.

Which means that instead of:

array(4) { [0]=> int(42) [1]=> string(6) "string" [2]=> bool(true) [3]=> float(3.1415926535898) }

You get:

Nothing new so far.

Xdebug 2.3 enhances the overloading of var_dump() with the inclusion of the file name and line number where var_dump() is called at. This has been a long standing feature request.

You can include this information, by setting xdebug.overload_var_dump to 2. If the xdebug.overload_var_dump setting is set to 2, the overloaded var_dump() output now looks like:

As you can see, the file name and line number of where var_dump() were called are prepended to the output.

An already existing setting, xdebug.file_link_format, allows you to format file name and line number information so that Xdebug generates a link. This same setting is also respected by the inclusion of the file name and line number in the enhanced var_dump() output. Setting xdebug.file_link_format to xdebug://%f:%l will then link the file name to xdebug:///home/httpd/html/test/xdebug/overload-var-dump.php:4. If we look at this as an image, we will see:

In a future version of Xdebug, it is likely that I will either wrap in the file name/line number information in the overloaded var_dump(), or change the default value of the setting to 2.


This article has a short URL available: http://drck.me/vardump23-bnb


Thanks Derick another great feature!

Questions from the Field: Should I Escape My Input, And If So, How?

At last weekend's PHP Benelux I gave a tutorial titled "From SQL to NoSQL". Large parts of the tutorial covered using MongoDB—how to use it from PHP, schema design, etc. I ran a little short of time, and since then I've been getting some questions. One of them being: "Should I escape my input, and if so, how?". Instead of trying to cram my answer in 140 characters on Twitter, I thought it'd be wise to reply with this blog post.

The short answer is: yes, you do need to escape.

The longer answer is a bit more complicated.

Unlike with SQL, inserting, updating and deleting data, as well as querying data, does not require the creation of strings in MongoDB. All data is always used as a variable or a constant. Take for example:

$c = (new MongoClient())->demo->col;
$c->insert( [ 'name' => $_GET['name'] ] );

Because we don't need to create a string with the full insert statement, there is no need to escape with ' to prevent issues like SQL injections. The context in which variables are used is immediately clear.

But be aware that PHP's request parameters (GET, POST, COOKIE, and others) allow you to send not only scalar values, but also arrays. If we take the example code from above in mind, and request the URL http://localhost/script.php?name[first]=Derick&name[last]=Rethans, we end up inserting the following document into the collection:

[ 'name' => [
        'first' => 'Derick',
        'last' => 'Rethans'
] ]

And this is probably not what you had in mind.

The same trick is possible when doing queries. Look at this code:

$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => $_GET['uid'],
        'password' => $_GET['password']
] );

If we now would request the URL http://localhost/script.php?uid=3&password[$neq]=foo we end up doing the following query:

$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => '3',
        'password' => [ '$neq' => 'foo' ]
] );

The password clause in that query, will likely always match. Of course, if you are not storing passwords as a hash, you have other problems too! This is just a simple example to illustrate the problem.

This same example highlights the second issue - that is that all request parameters are always represented by strings in PHP. Hence my use of '3' instead of 3 in the above example. MongoDB treats '3' and 3 differently while matching, and searching for 'user_id' => '3' will not find documents where 3 is stored as a number. I wrote more extensively about that before.

So although MongoDB's query language does not require you to build strings, and hence "escape" input, it is required that you either make sure that the data is of the correct data type. For example you can do:

$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => (int) $_GET['uid'],
        'password' => (string) $_GET['password']
] );

For scalar values, often a cast like I've done above, is the easiest, but you might end up converting an array to the string 'Array' or the number 1.

In most cases, it means that if you want to do things right, you will need to check the data types of GET/POST/COOKIE parameters, and cast, convert, or bail out as appropriate.


This article has a short URL available: http://drck.me/escinput-bm4


While relatively obvious to most Mongo users it's still a good summary. Everyone should burn this into his/her mind :)

Code Coverage: Finding Paths

Picking up from where we left last time, in this second article we will look at some upcoming functionality in Xdebug. Sebastian has been pressuring me for years to add branch and path coverage to Xdebug, with issue #1034. In the post I will show you what "branch and path coverage" is, and how it helps.

In the previous post, I showed you a trivial script as an example for code coverage. Let's have a look at a different script this time (article2-test.php):

function ifthenelse( $a, $b )
        if ($a) {
                echo "A HIT\n";
        if ($b) {
                echo "B HIT\n";

We now run this through PHP CodeCoverage (article2.php):

require 'vendor/autoload.php';
include 'article2-test.php';

$coverage = new PHP_CodeCoverage;

ifthenelse( true, false );

ifthenelse( false, true );

$writer = new PHP_CodeCoverage_Report_HTML;
$writer->process($coverage, '/tmp/code-coverage-article');

Which outputs:

And this nicely tells you that all your lines have been executed. However, you have not tested everything. With two if statements, there are four possible paths through your code:











But we have only tested for the second and the third cases. Because we are doing line coverage, this sort of coverage issues don't show up. In order to address this, we need to do branch and path coverage.

I wrote in the previous article that Xdebug follows all branches to find dead code during code coverage, but it never did really more with that. So, again, I started experimenting through VLD to see how I could get it to list all possible branches (easy) and paths through a function or method.

So now VLD would say the following (besides dumping the opcodes) about the code:

filename:       /home/httpd/html/test/xdebug/code-coverage/article2-test.php
function name:  ifthenelse


branch: #  0; line:     2-    4; sop:     0; eop:     4; out1:   5; out2:   8
branch: #  5; line:     5-    6; sop:     5; eop:     7; out1:   8
branch: #  8; line:     7-    7; sop:     8; eop:     9; out1:  10; out2:  13
branch: # 10; line:     8-    9; sop:    10; eop:    12; out1:  13
branch: # 13; line:    10-   10; sop:    13; eop:    14; out1:  -2
path #1: 0, 5, 8, 10, 13,
path #2: 0, 5, 8, 13,
path #3: 0, 8, 10, 13,
path #4: 0, 8, 13,
End of function ifthenelse

It's a bit difficult to see what goes on here, but in general there are five branches and four paths. The first two branches (0 and 5) are for the first if statement, the second two branches (8 and 10) are for the second if statement and the last branch (13) is the end of function, with an implicit return to the calling function. Branches are named after the opcode entry that forms the start of a branch.

Seeing the different branches is probably easier to see in a graph, which VLD can also produce (using the vld.save_paths=1 php.ini setting). This produces a paths.dot file in /tmp which we can convert to an image with GraphViz' dot tool:

dot -Tpng /tmp/paths.dot > /tmp/paths.png

And then this graph looks like:

With the functionaly added to VLD, the next step was adding this code to Xdebug. Xdebug needs to know about all the paths, but also need figure out which branches and paths are actually followed. It needs to overload every opcode (PHP's smallest execution unit) handler, as any of them could be at the start of a branch. Overloading each opcode handler makes running your code, a lot slower unfortunately when with branch/path coverage is enabled.

AlthoughPHP_CodeCoverage does not support it yet, it is possible to visualize the new path coverage with help from some helper scripts in Xdebug's contrib directory. As a similar example as above, the test script would look like:

require '/home/derick/dev/php/xdebug-xdebug/contrib/branch-coverage-to-dot.php';
include 'article2-test.php';


ifthenelse( true, false );

ifthenelse( false, true );

$info = xdebug_get_code_coverage();
file_put_contents('/tmp/paths.dot', branch_coverage_to_dot( $info ) );

This again creates a paths.dot file that we can convert to an image just like above:

dot -Tpng /tmp/paths.dot > /tmp/paths-covered.png

And then this graph looks like:

This clearly shows we have only covered two of the four possible paths through this particular function. PHP_CodeCoverage has not been updated yet to include this new functionality, so I made a mock-up in the mean while:

Now it's just waiting until Sebastian (or somebody else) has time to upgrade PHP_CodeCoverage to show the branch and path coverage. Happy hacking!


This article has a short URL available: http://drck.me/pathcoverage-blb


That's a very cool change. Wishing you all the best in having it implemented. I can't wait until I have to write exponentially more tests.

Has an issue already been opened for this over at the PHPUnit github repo? That might help to raise visibility, or allow people who want it bad enough to add a bounty to it (https://www.bountysource.com/ comes to mind, amongst others...)

From how i read it, and looking at the linked issue, this already has been implemented (Oh happy joy!)

Now Derick can start bugging Sebastian in return :)

@Oneway I think we mean the same thing... that this has not yet been implemented in PHPUnit_CodeCoverage. Unless I am missing something in which case I would love to know the issue URL :-)

Whisky Advent: part 4

December 19th: GlenDronach Parliament 21

This is another bottle that I got given as a gift for Xdebug. It is a 21 year old whisky from the GlenDronach distillery. This GlenDronach Parliament has been matured in a combination of Oloroso and Pedro Ximinez sherry casks. It is a bit stronger at 48% ABV.

Tasting notes: Very dark colour. Also very sweet, a tad spicy and hints of plums and other fruits. The sherry flavours are have a big overtone, but don't over power. The whisky ends with an oaky finish. A drop of water doesn't really help.

December 20th: Springbank 15

Tonight we have a Springbank 15, bought as a set of minatures from Cadenhead's to give away as wedding favours. As it is exactly six months ago since we got married, that seemed to be a fitting whisky to include. It is a Campbeltown whisky and not particularly special, but it reminds me of good times past. It was of course also quite nice of Cadenhead's to provide the minatures with a label with our names on it!. And, we did try out which whisky to pick as favours. We've tried a Springbank 10, 12 and 15, but the 15 year old won. Although I think we liked the 10 over the 12.

Tasting notes: Caramel, Vanilla, malty with some smokyness. Lingers long on the tongue with hints of pepper, and a flavour that sits all over the tongue. Well balanced.

December 21th: Cradle Mountain from Cadenhead

Another unusual whisky. Tonight's Cradle Mountain 15 is distilled by Small Concern Whisky Distillery, a distillery in Tasmania. It is bottled by Cadenhead at 57.9% ABV as part of their World Whiskies series. It has been aged for 15 years in ex. Jim Beam Bourbon Barrels. It is one of 186 bottles, and as you would expect with a single cask whisky, it does not have colouring added, or has it been chill-filtered.

Tasting notes: Very much in your face. It's sweet and syrup, but also oaky. The bourbon certainly has made its impression on this one. I would almost go as far as saying that it has more of a liqueur flavour to it than a "normal" whisky. It gets better with a drop of water, and the finish is long lingering with tropical fruits.

December 22nd: Highland Harvest Organic Batch 003

A bottle that I got as a birthday gift, which is fitting as today is my birthday! This whisky is certified organic and a blend of 7 casks. Each batch is a unique expression. This is batch 003 of this Highland Harvest whisky. It is bottled at 40% ABV.

Tasting notes: The colour is very pale. It's quite light, a little smoky and a taste of oak is very apparent. It's quite sharp, but also watery. The after taste is not very long, but what there is, is oak. I think this whisky should be aged more, as there is unfortunately very little character to it.

Morag says: It smells like blue cheese, and it would probably work great as a cocktail whisky.

December 23nd: The English Whisky 2010 - Chapter 9

Tonight's whisky is a dram from The English Whisky Company. Yes, a distillery from England. This Chapter 9 is the first ever English peated whisky, bottled at 46% ABV and is mixed from four casks. The distillery started distilling in 2006, and is therefore very young. The English Whisky Co. source their barley, yeast and water from within England, making this a truly English spirit. It is also a very young whisky, at only 3 years old. It is non-chill filtered, and it does not have colour added.

Tasting notes: Peated, light smoke. A bit watery on the palette, with not much of an after taste. You can easily taste that it is a very young whisky as it's rather sharp, but there are hints of citrus and pepper.

December 24nd: Glenmorangie Quarter Century

This is the most expensive whisky in my collection, but I don't think it is the best one. Some of the whiskies from Cadenhead's that I featured in earlier days in this advent calendar are several leagues ahead. Nonetheless, I am quite happy having a bottle of this Glenmorangie Quarter Century. It comes in a nice box too. I like this whisky even better, as it was another gift due to my work on Xdebug.

Tasting notes: It is a very rounded whisky, floral hints and citrus. The flavours are quite a mouth full and a lot is going on. There is also a toasty sweetness. It lingers a little while with a oaky after taste. A very enjoyable dram.


This article has a short URL available: http://drck.me/whiskyad4-b7f


No comments yet

Whisky Advent: part 3

December 12th: Auchentoshan American Oak

Tonight's dram is an Auchentoshan American Oak. It's from a bottle that I received as a gift for speaking at Glasgow PHP. Thanks! This Auchentoshan does not have an age statement, giving the bottlers a bit more freedom in which ages of barrels they use to blend with. It is possible that whiskies as young as three years are part of this "blend". This specific whisky is aged in first-fill Bourbon casks. Unlike many other whiskies on this calendar, it is both chill filtered and coloured.

Tasting notes: Over ripe fruits, oak, and a sour grapefruit finish. It's a little bland, and it has a short finish. It's still quite enjoyable.

Morag says: Slightly sharp nose, a little bit like vanilla. Not the smoothest with a hint of roughness. Short finish. Tastes like cardboard (or woody). Does not compare well to the Three Wood.

December 13th: Cadenhead's Glen Moray 21 year old

Another dram from Cadenhead's. It is a 21 year old whisky, distilled in 1992. It is part of their Wine Cask range and as usual, it is non-chill filtered and no colouring has been added. The 1992 CA is bottled at 55.4% ABV cask strength. A little curious is that the distillery on the label is Glen Moray-Glenlivet — the "Glenlivet" addition is not often seen anymore. There were only 216, and I'm afraid they are all sold out.

Tasting notes: It does need a drop of water to bring out some flavours—at 55.4% it is just a little bit too strong. Hints of sweeter wine, and cake. Perhaps a hint of aniseed and a finish of medicinal herbs. I'm not quite sure what to make of it really.

December 14th: Single Cask Aberlour 22 years old

I recently found the Whiskybase online, and noticed its extensive list of available whiskies. However, the whisky I had tonight was not known to them yet. I have since then added it.

The whisky is a 22 year old, single cask, cask strength whisky bottled by Speciality Drinks . This casks rendered 250 bottles and at 54.1% ABV it is a bit on the stronger side, and needs a little bit of water. I bought it at the Whisky Exchange as the bottle of the month1 for July. Interestingly the label on my bottle is different than what they have on their site.

Tasting notes: It is a very clear whisky. I taste hints of apple and cream. And with more than a hint of toffee. It lingers quite long with a hint of more toffee.

December 15th: Mortlach Càrn Mòr Strictly Limited

Tonight's dram is a whisky from the Mortlach distillery. Another whisky that the Whiskybase did not have! Or rather, I thought so. The search engine insisted that I spelled it "Mortlach Càrn Mòr" and wouldn't find it if I used "Carn Mor" :-/

This whisky is not from a single cask, but rather from two casks yielding 652 bottles. The whisky is non-chill filtered and has no colouring added. It is bottled at 46% ABV by Morrison and MacKay for their Strictly Limited range. The "two" whiskies are at least 16 years old and aged in Hogshead casks.

Tasting notes: Smooth and creamy honey on the tongue. Light summer fruits and caramel after taste. Could do with a few drops of water to make the flavours come out more.

December 16th: Millstone 1999 from Milroy's

The first non Scottish whisky in this calendar. Tonight we have a Dutch whisky, distilled in 1999 by Zuidam Distillery, and bottled by Milroy's of Soho in 2013. This Millstone 1999 is one of 271 bottles of a 14 year old single cask whisky matured in Sherry Casks. It is 46% ABV and again, non-chill filtered and it does not have colouring added. The whisky itself is quite dark of colour, rather like a sherry.

Tasting notes: Raisins, cinnamon, and a sweet sherry. The medium to longer finish is a bit oily and has a hint of oak and cherries.

December 17th: Yamazaki 18

This Yamazaki 18 from Suntory distillery is another non-Scottish whisky. As the name might hint at, this is Japanese. Some people might frown upon that, but "annoyingly", the Japanese actually make very good whiskies. This one, the Yamazaki is one of my favourites, but it does not come cheap. Luckily, it was given to me as a gift for my work on Xdebug. Since this Yamazaki 18, I've had another whisky, the Hakushu Distiller's Reserve that I actually like better. But that's empty.

Tasting notes: Very dark of colour. A little oily on the palette. Bubblegum, apricot and sweet fruits, a few herbs and spices. Fruits and woody flavours in the aftertaste that lingers quite a bit.

December 18th: Imperial 1994

This Imperial 1994 is bottled by Gordon & MacPhail as part of their Distillery Labels range. It is a first fill sherry butt and refill American hogshead. As the name suggests, it was distilled in 1994. The Imperial distillery is now closed though. This whisky was bottled in 2012 making it 18 years old. It is 43% ABV.

Tasting notes: Smells sweet, fruity and nutty. Smooth on the palette and vanilla, pepper and some tropical fruits in the aftertaste.


This article has a short URL available: http://drck.me/whiskyad3-b77


No comments yet

  • 1

    The "bottle of the month" is a longer running project. I will blog about that at some point later.

  • 2

    The "bottle of the month" is a longer running project. I will blog about that at some point later.

Life Line