It’s a known fact: programmers spend more time debugging than coding. I remember when I was just starting out, I spent a lot of time just poking at code in the hope that bugs would magically disappear (don’t do that)! Imagine all the time I lost.

In this article, I’ll give you a couple of tricks to be efficient in this not so exciting, but crucial task that is debugging code.

Here’s a quick list of all the tips I wrote about:

If you know any other tip that could help programmers debug their PHP, don’t hesitate to tell us in the comments! :)

Tip #1: Direct access to your code!

This is self-evident for professional developers, but for people just starting out this could be not so obvious. If you’re changing the code of your PHP files on your computer, then connecting to an FTP server, then uploading your PHP file, then refreshing your browser to see if it works… well… don’t be surprised if the 90s call and ask for its technique back.

This is not an efficient way to debug code. Actually, this is the “ghetto way” of developing for the Web.

The problems with this “technique” are not only related to the efficiency of debugging, it’s a really bad programming practice. Just don’t do it. Take one hour to install PHP on your system if you don’t have a test environment.

It’s out of the scope of this article, but you could just search Google for “How to install PHP on Windows” for example. An even better way to work is to use a virtual machine. Using PuPHPet with Vagrant and Virtual Box is not so hard and you can even have a Linux box on Windows! No more capitalization problems!

If you possess a distant server for your tests, check with your hosting company if you can have a remote desktop access or a direct shell access. It’s still less efficient than to have PHP installed on your local machine, but it’s a 100 times better than FTP-ing.

Direct access to your code won’t make finding bugs easier, but it will be more efficient.

Tip #2: Find the error messages!

Your code doesn’t work and you see nothing except that the browser doesn’t do what it’s supposed to do? Well, is there any error?

A quick trick is to just check error reporting by generating an error like this:

<?php bug(); ?>;

You should see an error like the following:

Fatal error: Call to undefined function bug() in ../apache-2.2/htdocs/test.php on line 2

If you do see it, it’s good! Well, except if you’re on a live website because that would be bad for security and for user experience. But that’s for another article!

If you don’t see the errors, you can configure the error settings in your php.ini file. Find those lines and set the values like this:

error_reporting = -1
display_errors = On
display_startup_errors = On
log_errors = On

Note: You might have to restart Apache or php-fpm if you’re on Nginx for the modifications to take effect.

Again, those settings are for your test environment. Do not use those settings for a live/production website!

Now, if you still don’t see the error in your browser even after the configuration change, it’s OK, don’t worry. First, maybe it’s hidden in the HTML sources. It can happen when an error breaks the HTML of a page. Just check the HTML source code of the Web page (CTRL+U or CMD+U on most browsers) and search for “Fatal”. Did you find something?

If it’s still not there, here’s the trick you can use directly in your code (or if, for some reason, you don’t have access to your php.ini file):

ini_set('display_errors', '1'); 
error_reporting(E_ALL | E_STRICT); 
... your code here ... 

This will “override” the value in the configuration file in PHP or any other value that could be set before your code.

As of PHP 5.3, the E_STRICT constant is available. You should know that it’s not included in E_ALL, so that’s why I added it. It will warn you on code usage which is deprecated or which may not be future-proof.

Here’s the value you should use depending on your PHP version:

Less than 5.3: use E_ALL or -1
5.3: use E_ALL | E_STRICT or -1
greater than 5.3: use E_ALL or -1

By using E_ALL, you should also see the “notices” such as “undefined variable”. It’s a good idea to clean those warnings too as it could prevent other nasty bugs to appear along the way.

To see what is the actual value of “display_errors”, you can use this line of code:

echo ini_get('display_errors');

If you see 0 (zero) or “Off”, then it won’t display any error message directly on your Web pages.

If you don’t want to display the errors directly in your Web pages, it’s fine too. You will need access to the error logs.

If your PHP is served through Apache, the logs are usually in Apache’s installation directory under the “logs” folder. You will obviously need a direct access to the computer where Apache is installed.

For Nginx with php-fpm, if it’s activated, it should be in php-fpm’s error log.

To read those files, you should use a “tail program”. To find one, go on Google and look for “tail program for Windows” for example. Those programs will display the changes in the error logs instantly. I use BareTail for Windows.

Personally, I will favor displaying errors directly inside the HTML Web page. Sometimes, it will help you find where the error is happening. For example, if you see that a piece of code was executed (because the Web page shows the result), you know that the error happened after this piece of code.

Also, the probability of not seeing an error written directly on a web page is fairly low opposed to a log file.

Tip #3: Use a debugger and breakpoints!

Sometimes, the bugs are sneaky or the error message is not really clear. Breakpoints are a great way to debug your code and you should use it for those subtle “hard to find” bugs.

For breakpoints in PHP, you will want to use XDebug. With a graphical debugger, it makes it easy to step through code, inspect variables, and use breakpoints live while the code is getting executed.

The complete steps to install XDebug can be tricky and it’s out of scope for this article (it’s in my todo list ;) ), but here’s the general idea:

  1. Activate remote debugging on your test PHP server
  2. Use a client supporting XDebug remote connections
  3. Add breakpoints and enjoy the extra debug info!

To enable XDebug on a server, you should change the following settings in php.ini:


Note: You will have to restart Apache or php-fpm (Nginx) for the modifications to work.

The parameter xdebug.remote_host should contain the IP address of the computer where your will debug your PHP. This will be easier if your server is running on the same computer as your IDE or, at least, on your local network.

If the server is somewhere on the Internet, there’s a good chance that a firewall or you router won’t allow the connection.

All in all, using breakpoints is way more efficient to find sneaky bugs than using the classic and less glamorous way of outputting information straight to your Web page using “echo” or “print”.

Tip #4: Add debug information to a log file!

This is not exactly a tactic on “how to debug” but this will help your debugging along the way. Especially when working on big projects when bugs can happen on production servers.

When you get to an unexpected place in your code, you can add more data to the standard error log file with error_log. Here’s an example:

try {
} catch (Exception $e) {
    error_log('Error after doStuff()! Here\'s the message:' . $e-&gt;getMessage());
    // more stuff ... (clean stuff, die(), etc)

With the “error_log()” method, you can also send the logs to another file or by email.

Additionally to error logging, you could also add debug information to a logging file. By default, PHP doesn’t offer different log levels (like info, warning, debug, etc.) but if you’re using a framework, there should be something out of the box.

For example, there is “log_message()” with CodeIgniter or the “Log” class in Laravel.

You could also use standalone log modules/classes like Monolog or KLogger.

Just be careful not to add too much noise in your debug logs. If there’s too much info and you can’t use it, it’s not really helpful! ;)

Tip #5: Sandboxing bugs!

You will get better at this with experience. It’s a little bit like playing the game Clue. You suspect a couple of pieces of code and you gradually eliminate those pieces to find the guilty one.

Let’s imagine that an error occurred in a piece of code that retrieves information from a database and does calculations with the returned data. For some reason, the error message is not clear. Also, let’s pretend that you use a framework. Here’s the steps you could take:

  • Connect to the database with a standalone client (like MySQL workbench) from the server where the faulty PHP is executed. That way, you will know if the server can access the database or not.
  • Also, check to make sure that you are using the same credentials as your PHP code does (same username, same password).
  • Try the query directly in the SQL client to see what data is returned.
  • Start a small PHP script without a framework around.
  • Add simple code to connect to the database to that script.
  • Add the code to retrieve the information.
  • Check the information returned from the database.
  • Add the code that does the calculations.

Somewhere along those steps, you should find the real bug or at least have a better idea as to where the problem is coming from.

It could be that the database is not available. Maybe the user connecting to the database doesn’t have the required access. It’s possible that the data returned are not what the code expected. There could be a lot of places where the bug can originate from.

If you can’t find a problem in your standalone PHP file, you can start to suspect your framework. Is it a bad configuration? Is it something you added to your framework that makes it behave like a crazy monkey?

The next step would be to start from scratch with your framework and your standalone code only. Does it work? If it does, then you can investigate the plugins or configurations in your framework where your code doesn’t work.

Tip #6: Duck debugging

Before you call me crazy, this technique really exists, I didn’t invent it!

So, if you cannot find that - insert curse word here - bug and you’re about to throw your computer by the window, explain the code to somebody else (like a coworker) or, if you’re alone, to (yes, really) a rubber duck.

Just explain to it, line by line, what it’s all about. It doesn’t matter if you talk to another programmer or an inanimate object that knows nothing about programming.

The process of going line by line, explaining what it does out loud often help find where the problem lies. It might sound crazy, but it works!

Note: I didn’t try with a real duck, but I eared that it works too.


I hope those six tips will help you make your debugging sessions a little bit more enjoyable! Also, don’t hesitate to share your tips in the comment section!

Picture by Rovanto