How to setup and use the Xdebug Extension for PHP Profiling

A profiling tool can provide valuable information about bottlenecks in your code. I believe profiling is a critical aspect of optimizing because it will tell you about your real code bottlenecks as opposed to your perceived bottlenecks. This enables you to focus your resources on areas that will provide the most performance benefit for your effort. Most programming languages and environments have one or more profiling tools available and PHP is no exception.

Xdebug is a PHP extension that provides valuable debugging information such as stack traces, functions traces, profiling, code coverage analysis, etc. There is another PHP tool called DBG that has similar functionality but this post will focus on using Xdebug.

Setup Xdebug

Xdebug is a PECL module and can be installed using the PECL installation instructions in one of my previous posts.

  • If you have already setup PEAR you just need to run the following from a shell:
    sudo pecl install xdebug

    If everything goes well Xdebug should download, build, and install. You may get a message telling you:

    You should add "extension=xdebug.so" to php.ini

    Go ahead and add the line. On an Ubuntu server you will probably find the php.ini file here: /etc/php5/apache2/php.ini

  • Restart Apache, or whatever web server you are using, so the change will take effect.
    If you are running Apache on Ubuntu it would be:

    sudo /etc/init.d/apache2 restart
  • Write a phpinfo.php page with the following code and then point a browser at it. It should show the Xdebug module there in addition to many other things:
    <?php phpinfo(); ?>

At this point the Xdebug extension should be installed. For more detailed instructions on a PECL extension install see my post: How to install a PHP PECL extension/module on Ubuntu. Note that there is a problem running the Xdebug extension with Zend Studio since it has it’s own debugger.

Enable Xdebug profiling

  • By default, profiling is disable in Xdebug. Enable it by adding the following entry to the php.ini file:
    xdebug.profiler_enable=On

    On on a linux box there is often a php.d or conf.d folder that holds additional .ini file settings PHP will use. On Ubuntu the path for this folder is “/etc/php5/apache2/conf.d”. To prevent further cluttering my php.ini file with Xdebug settings, I created a xdebug.ini file to store all my Xdebug .ini file settings. This file is located in the “/etc/php5/apache2/conf.d” so it is automatically scanned when Apache is restarted.

    Now you might be tempted to enable the profiler in your script using the ini_set() function which, normally allows you to temporarily set a .ini setting for only the current script execution. Unfortunately this does not work. You must set it in the php.ini or a sub .ini file and restart the web server.

  • Restart your web server (I.e. Apache) once you have “xdebug.profiler_enable” set to “On”.

By default, Xdebug will write a cachegrind.out file to the /tmp folder. It will be named something like cachegrind.out.22373 where the number at the end is the ID of the process that was profiled. If you are using Windows you will probably need to change the default folder. Also by default, this file will be overwritten by each script execution so you don’t have to worry about it getting too big. The output file behavior is highly customizable and a complete list of Xdebug settings can be found here.

Call your script and display the analysis

With Xdebug enabled, pull up the page in your browser that you want to profile. If everything is working OK a cachegrind.out file should show up in the /tmp folder.

There are a couple programs you can use to open and analyze the cachegrind file:

WinCacheGrind

WinCacheGrind is not very featured but it will tell you the main thing you need to know, which is where your PHP application is spending its time. Click on the screen shot below to see the full output of my test script:

wincachegrind screen shot

The script makes an external call to example.com using a file_get_contents() function. Based on this analysis I might try caching the call results and only make the call at some interval to keep the cache updated. This would eliminate almost 75% of the application’s overhead and is just one example of an easy-to-fix bottleneck that profiling will help identify.

KCacheGrind

KCacheGrind does essentially the same thing as WinCacheGrind but it is geared for the Linux desktop and has quite a few more bells and whistles:

kcachegrind screen shot

KCacheGrind includes a map feature that graphically represents the percentages of where the test application spent the time:

kcachegrind screen shot

KCacheGrind also includes a graph feature with an export option that displays a tree diagram of the linkage between all the includes and functions:

kcachegrindexport1.jpg

That’s it for this post. Have fun profiling!

Review: RC Wall Climber/Clamber Remote Control Mini Car (Updated)

2 out of 5 stars

RC Wall Climber/Clamber Remote Control Mini Car

Update: Warning

I have received at least one report of a non-working car and the manufacturer has does not seem to have a web site that I can find to get a replacement. I have downgraded my rating to 2 stars accordingly. If you buy one of these make sure you get it from some place you can return it if it doesn’t work.

NeweggMall.com recently sent me an e-mail pushing a wall climbing RC car called the Clamber!!! Master-Hand. It is actually listed under RC Wall Climber Remote Control Mini Car but the name on the box is “Clamber!!! Master-Hand” by Top Race R/C Series. Although similar, this is not the same as the Spinmaster Air Hogs Zero Gravity Micro Cars, which are a bit more expensive. It was cheap and cool enough looking that I naturally felt compelled to give it a try.

How it works

If you are not familiar with these, they have a vacuum inside that holds them to the wall. The four outer visible wheels are actually fake and just look nice. There are two inner wheels that are not visible (unless you flip it over) that sit against the wall and propel the car.

The switch on the back has three different modes: off, on without vacuum, and on with the vacuum. This way if you just want to run it on the floor you don’t have to turn on the vacuum and waste your charge.

The underside has two strips of fabric that sit against the wall to help maintain the vacuum. There are two intake holes on the bottom and 4 slits in the windows on top for the air output.

The car itself looks pretty cool although the fake tires are a little less than authentic. It comes in three colors: Red, Black, and Blue.

Performance

The car does not go too fast but fast enough. It drives similar to a tank because it is actually only using two wheels. To steer, it changes the speed of the wheel on the appropriate side. While you are driving the turn radius is not precise and tends to be a bit large. When you are stopped it will turn on a dime.

As power starts to run down, the vacuum does not hold the car as tightly to the wall as a full charge so sometimes the drives wheels will start to slip and you have to turn around and go in a different direction to get moving again.

Run time on the wall is about 7 minutes although performance slopes off and the car will start loosing its traction around 4 minutes. Even after 7 minutes the vacuum was still strong enough to keep the car on the wall. I didn’t time it but I am guessing run time on the floor without the vacuum on would be quite a bit longer. When you get close to 8 minutes the power will cut off before the battery is drained too far. It uses a built in Lithium-Polymer battery which is probably why a charge last as long as it does for something so light. Charge time is about 10 minutes.

Here are some pros and cons:

Pros

  • Pretty good amount of drive time per charge (about 7 minutes)
  • Only a 10 minute charge
  • Can rotate on a dime while stopped
  • Fun!

Cons

  • It will get stuck on even flat, clean surfaces occasionally after the battery has run down a bit.
  • The turn radius between running and when it is stopped is quite different. When it is stop it turns on a dime. When it is running it has a very wide turn radius in some cases.
  • IR controller does not perform well under strong light.

Conclusion

Overall I rate the wall climber 3 out of 5 stars. I would give it more stars if the steering were a bit more consistent and it didn’t get “stuck” as often. Overall it was pretty fun but I would say the Microfly is a bit more entertaining just because for about the same price or less, it flies around and that is hard to beat in my opinion.

Images

RC Wall Climber Clamber Remote Control Mini Car

RC Wall Climber/Clamber Remote Control Mini Car

RC Wall Climber/Clamber Remote Control Mini Car

RC Wall Climber/Clamber Remote Control Mini Car

RC Wall Climber/Clamber Remote Control Mini Car

RC Wall Climber/Clamber Remote Control Mini Car

RC Wall Climber/Clamber Remote Control Mini Car Charging

Video

Review: Senario NRG MicroFly RC Hovering UFO

3 out of 5 stars

Senario NRG MicroFly RC Hovering UFO

In a previous post I talked about the Senario Alien Microfly a bit and in this post I will provide a full review. I gave a few units to some of my family for Christmas so I have flight reports from them as well.

The Senario Alien Microfly kit comes with a transmitter and the Microfly itself. The transmitter takes 6 “AA” batteries and also serves as the charger for the Microfly. It is pretty small (see the pictures below) and a lot of fun to fly around the house or office.

I put in many, many flights. Each flight is about 5 minutes with a 15-20 charge time. The cats gave it a few taste tests but mostly they like to just stalk it as it flies around the living room. 😉 I bought 5 of these for myself and my family for Christmas and all of them worked out of the box. Here is a list of pros/cons:

Pros

  • It is simple to fly. There is only one control to make it go up or down so you don’t need a lot of experience.
  • Cheap. You will probably find it for $25 or less.
  • Durable. You can’t sit or step on it (it is mostly just foam board) but mine has been through many crashes and even survived a few taste tests by the cats.
  • The flight time is about 5 minutes which I think is pretty good for something so small.

Cons

  • In very large rooms (gym/church/wharehouse) it can quickly get out of range if it doesn’t have walls for the IR signal to bounce off of.
  • After running through three or four sets of “AA” batteries (rechargable) flight times have fallen off quite a bit although I did get many flights on each set of batteries
  • Fragile. Although it can withstand being bounced off a few walls it is very small and made of foam so you don’t want to leave it someplace where it will be sat/stepped on.
  • No directional flight. It only goes up and down.
  • Charge time is kind of high… about 15-20 minutes per flight

Conclusion

Overall I give the Microfly 3 out of 5 stars. I would easily rate it higher if it maintained its power after extended use. I don’t know if the built in battery has just been recharged too many times or if the motor is reaching the end of it’s life since it is so tiny and spins at such high RPMs. Despite this, I would say it is easily worth the price and would recommend it to anyone that enjoys RC toys.

Images

Senario NRG MicroFly RC Hovering UFO

Senario NRG MicroFly RC Hovering UFO

Video

Note: If you don’t see a video click here.

How to use the file_get_contents() function to make an HTTP request from PHP

In a previous post I talked about using the HttpRequest object and functions in the PECL_HTTP extension to make HTTP requests from PHP. In some cases you may be limited to using functionality built into the PHP core. The file_get_contents() function has less features than the PECL_HTTP extension but it is built into PHP 4.3 and up. Here is an example of using it to retrieve the landing page at www.example.com:

<?php
 
echo file_get_contents("http://www.example.com");
 
?>

Someone hit that easy button.

The file_get_contents() functions as well as many other PHP file functions implement a streams abstraction layer largely conceived by Mr. Wez Furlong. This abstraction layer is what enables many of the PHP file functions to access network resources. Given this functionality “file” seems a misnomer.

The file_get_contents() function uses an HTTP GET request but what if you want to do a POST without using cURL or the PECL_HTTP extension? Furlong posted an article here on how to do just that.

This next code example uses the file_get_contents() function again but this time a few options are set first using the stream_context_create() function:

<?php
 
$http_options = stream_context_create(array(
    'http' => array(
        'user_agent' => "Mark's Browser",
        'max_redirects' => 3)));
echo file_get_contents("http://www.example.com", false, $http_options);
 
?>

Note that the array passed to the stream_context_create() function can also be used to specify a POST method, which is how Furlong does so in his blog post.

There is still yet another way to make an HTTP request from PHP that I haven’t covered yet using the PHP built-in cURL functions. I will cover these in a separate blog post.

How to make your PHP application check for its dependencies

The very informative phpinfo() function

The phpinfo() function displays just about everything you want to know about your PHP installation. It includes info on all your PECL and PEAR modules so it is a quick way to check what’s installed. It will also tell you useful web server information including any query strings you pass. To display all this good info just point your browser at a page on your server that contains the following code:

<?php
 
phpinfo();
 
?>

That’s it!

Automatic dependency checking

The phpinfo() function will give us a page that displays a lot of info. You can pass it bitwise constants to narrow down the information displayed but what if we want to check for specific items?

In my humble opinion, when developing software or anything in general, it is a good idea to design things so that the end user will not even need a manual because the user interface is obvious. When something doesn’t work, it should be equally obvious how to fix it.

If you write a PHP application that others will install and use, it is a good idea to check for dependencies when they try to use the application. This way even if they don’t read your documentation they will quickly know why the software is not working.

Using phpversion(), PHP_VERSION, and version_compare() to check the PHP verson

To get the core PHP version you can use either of the following methods:

<?php
 
echo phpversion();
echo "<br/>or<br/>";
echo PHP_VERSION;
 
?>

The above code should output something like this:

5.2.6-2ubuntu4
or
5.2.6-2ubuntu4

If you are using Ubunto or some other distribution, you will note that some additional stuff is tack on to the version number (I.e. “-2ubuntu4”). This makes a comparison to your expected version a little tricky but you can use a substr()/strpos() combo to get what you need. There is an easier way to do the comparison though. The version_compare() function is “PHP-standardized” version aware. So we can do something like this:

<?php
 
if (version_compare(PHP_VERSION, '5.0.0', '<')) {
    echo 'You are using PHP version ' . PHP_VERSION . 
      'This program requires PHP version 5.0.0 or higher.';
} else {
    echo 'You are using PHP 5.0.0 or higher. You are all set!';
}
 
?>

Now you can check the PHP version and notify the user if it is not the minimum required version.

The PHP function documentation for each function at www.php.net include the PHP versions that contain the function in the upper left hand corner:

substr function version on php.net

You can use this to learn what versions of PHP include the functions you are using in your code to help identify your minimum PHP version requirement.

Using get_loaded_extensions() to check for extensions

The get_loaded_extensions() function will return an array of PHP extensions that you can use to check if a specific extension is installed. Use it in combination with with the in_array() function to check if the extension you require is loaded. In this example I check if the PECL_HTTP module is installed:

<?php
 
if (in_array("http",get_loaded_extensions())){
    echo 'The PECL_HTTP module is installed. '.
      'You are all set!';
} else {
    echo 'The PECL_HTTP module is not installed. '.
      'Please install it.';
}
 
?>

You can use the phpversion() function to check if extension is listed and if so, its version. This code example not only checks if the PECL_HTTP module is installed, but also checks it’s version:

<?php
 
if (!phpversion('http')){
    echo 'The PECL_HTTP module is not installed. '.
      'Please download it from '.
      '<a href="http://pecl.php.net/package/pecl_http">here</a> '.
      ' and install it.';
} else {
    if (version_compare(phpversion('http'),'1.6.0','>=')){
        echo 'The PECL_HTTP extension is installed and '.
          'version 1.6.0 or higher. You are all set!';
    } else {
        echo 'Please upgrade your PECL_HTTP extension to '.
          'version 1.6.0 or higher. You can download it '.
          '<a href="http://pecl.php.net/package/pecl_http">here'.
          '</a>.';
    }
}
 
?>

Use function_exists() to check for individual functions

So far the methods for checking dependencies have been somewhat broad. They check that the script has a certain version of PHP or extensions installed and that will likely be good enough in most cases. If you really want to be thorough you can also check if specific functions are available using the function_exists() method. In this example I check that the http_request() module, which is part of the PECL_HTTP extension, is there before I use it. If it is not, I use the less featured, built in, file_get_contents() function.

<?php
 
if (function_exists("http_get")) {
    echo 'Using the http_get():<br/>' .
        http_parse_message(http_get("http://www.example.com"))->body;
} else {
    echo 'Using the file_get_contents():<br/>' . 
        file_get_contents("http://www.example.com");
}
 
?>

Check for include files

Here is a simple way to check for include files. It doesn’t verify their content but you can at least make sure they are there:

<?php
 
if (!file_exists('httptest.php')){
    die('The httptest.php include file is missing.');
} else {
    require_once('httptest.php');
}
 
?>

Wrap up

Checking dependencies is an important part of building robust software and hopefully the above techniques will help accomplish that. Even if your end user is a very technical they will likely appreciate a good dependency checking mechanism that quickly tells them whats missing to save them time. If your software will be used by non-technical users you might want to automatically and gracefully downgrade your software feature set instead of generating errors and asking them for something they won’t know how to do. Usability is king!