Box.net Technical Blog

How to Debug PHP with Vim and XDebug on Linux

posted by Sam Ghods

Here is the scenario: You have multiple developers logged into a Linux server which is running Apache and PHP using Vim to write PHP code. They’re using error_log and echo statements to debug their code. It takes forever, it’s tedious and can result in bugs from forgotten debug statements. You stare enviously at .NET programmers with fancy debuggers (while you snicker knowing that you edit 10x faster with Vim anyways). But still, you know there has to be a better way.

There is.

Here’s how it works. You’re coding away in vim. You hit F5; Vim waits for a connection from the PHP server. You refresh the PHP page you’re working on. It attempts to contact Vim — connection successful. You are launched into a debugging session right inside Vim. You can step into, over, and out of statements, eval statements, get all variables in context, get and set properties, remove and set breakpoints, all on the fly. Finally, some real programming tools.

The environment: Vim

First, we need to make sure vim is compiled correctly.

Type :version in your Vim and check the features section. If you have +python and +signs, you’re good to go. Skip ahead to the next section.

Otherwise, you need to compile from source. On Linux, download and untar the source code, and open up src/feature.h. You need to comment out the conditional statements around the +signs feature. In Vim 7.1, it looks like this:

/*
 * +signs       Allow signs to be displayed to the left of text lines.
 *          Adds the ":sign" command.
 */
#if defined(FEAT_BIG) || defined(FEAT_SUN_WORKSHOP) \
        || defined(FEAT_NETBEANS_INTG)
# define FEAT_SIGNS
# if ((defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \
        && defined(HAVE_X11_XPM_H)) \
    || defined(FEAT_GUI_GTK) \
    || (defined(WIN32) && defined(FEAT_GUI))
#  define FEAT_SIGN_ICONS
# endif
#endif

You need to comment out both if statements and their respective endif’s, so it looks like this:

/*
 * +signs       Allow signs to be displayed to the left of text lines.
 *          Adds the ":sign" command.
 */
/*#if defined(FEAT_BIG) || defined(FEAT_SUN_WORKSHOP) \
        || defined(FEAT_NETBEANS_INTG)*/
# define FEAT_SIGNS
/*# if ((defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \
        && defined(HAVE_X11_XPM_H)) \
    || defined(FEAT_GUI_GTK) \
    || (defined(WIN32) && defined(FEAT_GUI))*/
#  define FEAT_SIGN_ICONS
/*# endif
#endif*/

then cd back to the top source directory and run:

./configure --enable-pythoninterp

If on a 64-bit system or a system with a strange python installation, you may have to add --with-python-config-dir=/usr/lib64/python2.3/config to the configure string. If the configure script can’t find the config directory it will say so in the script output, but the configure won’t explicitly fail — so you have to be sure that all the python stuff is OK.

After configuration, do

make && make install

to install your newly python’d vim.

The client: Debugger.vim (and Debugger.py)

Now that vim is ready, download the DBGp client script. Extract the two files (debugger.vim and debugger.py) to your vim plugin directory or your .vim home directory. In Vim 7.1 compiled on Linux, the default load-for-everyone plugin location is /usr/local/share/vim/vim71/plugin/, so you would put both files in that directory.

Try to run vim — if you get no errors, everything should be good. If you get an error, double check :version to make sure +python and +signs are there. If they are, post a comment here with the vi error you get. If they aren’t, the vim compilation/installation didn’t work — go back and try it again.

Now your debugging client is ready. Now let’s setup the server.

The server (engine): XDebug

Download XDebug. Download the source, compile the .so and add the following lines to your php.ini:

[Zend]
zend_extension = /full/path/to/xdebug.so
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.remote_host = localhost

Open a file in your browser which outputs <?php phpinfo(); ?> to make sure xdebug is loaded.

XDebug in phpinfo()

Now, with your site being example.com, go to http://example.com/index.php?XDEBUG_SESSION_START=1. This will set a cookie in your browser which expires in 1 hour which tells the PHP XDebug module to try to make a connection every time a page loads to a debugging client which is listening on port 9000. The cool thing is that if it can’t make a connection, it just keeps loading the page, so there’s no issue just leaving the cookie on.

Now go back to vim and press F5. You should see a message like “waiting for a new connection on port 9000 for 5 seconds…” at the bottom of the screen. You have five seconds to now refresh the PHP page. This will create a connection between the debugger and client. Now you’re debugging. Follow the instructions in the Help window to step into, over and out of code. Press F5 to run the code until a breakpoint (which you can set using :Bp).

DBGp client in Vim

But what if I have multiple developers on the same machine?

No problem. Simply set g:debuggerPort in each developer’s .vimrc to get the client listening on a different port. So if you wanted one developer to connect on 9001 instead of the standard 9000, you would add this line to their .vimrc:

let g:debuggerPort = 9001

Getting the server to connect on a different port is a little trickier. You need to set a custom php.ini value (xdebug.remote_port) for each user. It works best if you’re using VirtualHost’s in Apache. Just add the following line to the VirtualHost section of your httpd.conf:

php_value xdebug.remote_port 9001

Now restart Apache and if you use that VirtualHost and that vi user, then they should connect successfully.

That’s about it

Please post any questions or suggestions you may have. I hope this helps a few of you out there who want debugging tools but don’t want to give up Vim editing. Also be sure to post any alternate methods, or any patches or improvements to the remote PHP debugger vim script, and I’ll be sure to incorporate them.

[Note: This is the first in a series of posts we’ll be doing along the lines of tutorials, tools we’ve developed, tech commentary, and so on. Please feel free to subscribe, as well as leave any comments, thoughts or suggestions below so we can be sure to improve with each article! Thanks!]

32 responses to “How to Debug PHP with Vim and XDebug on Linux”

  1. Trenton Weir says:

    Thanks, this looks very interesting, but the link to ‘DBGp client script’ doesn’t work.

  2. Sam Ghods says:

    Thanks! This has been fixed.

  3. […] how-to-debug-php-with-vim-and-xdebug-on-linux/ […]

  4. […] 详细内容 […]

  5. Erik Schwartz says:

    This is a great tutorial — thank you very much for the effort. I run Feisty Fawn with backported php 4.3.10-10ubuntu3 and everything worked great.

    The one question I have is about debugging forms. Does anyone know of a way to begin debugging a page once a form has been submitted with xdebug+vim? I currently use the Zend Client and this feature has proven extremely useful. I’m really hoping to move to an open source environment and I’ve not been able to configure Eclipse PDT, Protoeditor, or PHPEclipse to work on my machine. This seems like a great solution but I hope to discover a native form debugging capability.

    Cheers and thanks again,
    Erik

  6. Erik Schwartz says:

    Scratch that last comment — my apologies. It’s easy enough to debug a form by submitting it the 5 second window after pressing f5 in vim.

  7. Ben Giles says:

    thank you for keeping the xdebug vim script alive!

  8. Brownie says:

    Hey Just letting anyone know Xdebug can work as both as an extension and a zend_extension (eg. the ubuntu pecl install initially suggests you add extension=xdebug.so which works fine for profiling)..

    The debugger will only work if its loaded as a zend_extension (as it is of course explained in the blog) . but I still managed to get caught!. The debugger will initially look like it was working but fail when it tries to set the breakpoint.

    hope this helps someone else. Many thanks for the article

  9. Wally Brock says:

    Works with Mac OS X as Well!

    Even though the tutorial says “Linux” this also works on Mac OS X as well.

    Thank you for an excellent tool!

  10. I wrote a set of articles on debugging PHP (mainly Drupal), see Developing, tracing and Debugging Drupal, and an article on setting up xdebug DBGp for PHP on Debian/Ubuntu, as well as using vim and xdebug DBGp for debugging Drupal or any PHP application

  11. Box.net: How to Debug PHP with Vim and XDebug on Linux…

    Curt Zirzow has pointed out a cool article on the Box.net ……

  12. […] Zirzow has pointed out a cool article on the Box.net website about debugging your PHP applications with a combination of Vim and XDebug […]

  13. Great post as I like to use vim from time to time when Komodo pisses me off. I’m running this on OS-X and had no problems getting it run, but I couldn’t see in the debugging window what the values of the variables at that point would be like I would see in Komodo. Any tips on that?

  14. […] a cool article on using debugging PHP using XDebug in vim. Sometimes Komodo gets resource hungry and a quick drop into vim usually makes me feel […]

  15. Sam Ghods says:

    Chris,

    Do you mean just having a watch window which displays pretty much any variable currently in the scope? That would be pretty cool… the client script doesn’t implement it currently but it shouldn’t be too hard. I think you would just have to run the get_defined_variables() PHP function after each time the debugger pauses and put the results stuff in one of the windows. I don’t have the time or Python experience to rig that up at the moment but if anyone wants to write that in and send me a diff, I’d be more than happy to incorporate it in the script and publish it on the vi plugin page.

  16. Running MacVim (vim 7) I had to use Andrei’s modified debugger.py file to get it working. It’s available at: http://www.gravitonic.com/blog/archives/000357.html along with some excellent slides for anyone who’s new to vim.

  17. […] linked to How to Debug PHP with Vim and XDebug on Linux. I started reading but then I realised I had to compile Vim again! I’ll stick with my […]

  18. Sam,

    Yes, that’s exactly what I’m talking about. In Komodo when you use their built-in support for XDebug they provide you with a small window that shows you all the variables currently in scope and their values. I find that very useful as I’m trying to wean myself off of the old print_r and echo style of debugging.

  19. Gavin says:

    Hey. Just wanted to point out that you can install xdebug with pecl install xdebug
    On Ubuntu you might/will need to install build-essential and possibly other packages.

    Gav

  20. Gavin says:

    The webserver and the machine I’m typing on are two difference machines. Is that a problem?

  21. Sam Ghods says:

    Gavin,

    Not a problem, as long as the webserver has access to your debug machine. Simply change xdebug.remote_host = , and change xdebug.remote_port = . The only problem might be that you might need to set up your router or firewall to allow and route incoming requests to port 9000 (or whichever port you choose) to your local machine. Good luck!

  22. Gavin says:

    Aaaah yes. Thanks, that was it. Next question :)

    I set a breakpoint in a script inside my framework; when I debug it stops at line 1 of the first script. Pressing lands me back at line 1 of script 1. Pressing again shows me “Connection closed, stop debugging etc”. Am I doing something wrong ?

    Also, I was thinking about the keys. I already have F1-F12 mapped. I tweaked debugger.vim to (only) use “d*” with * being something appropriate (although you already had some d mappings.) It might make the script less invasive.

    gav

  23. Gavin says:

    Can I file bug reports here ?

    get_property_at_cursor doesn’t handle static properties of classes e.g.
    I want to see the value of

    App::$route

    but the watch window says

    property_get: $route

    .

  24. Gavin says:

    re the keys: earlier. I “meant” to talk about the script using
    Leader d*, but my “html tags” were stripped:

    d*

    gav

  25. dbu says:

    [this was a “bug” report, until i realized my setup was wrong. now its just a bunch of tips:]

    if you want the +signs and +python on ubuntu, just do ‘apt-get install vim-python’ if you don’t want to compile it yourself.

    instead of telling something of a timeout, my vim tells me “DbgProtocol instance has no attribute ’stop’” if nothing connected to it for 5 seconds.

    if your phpinfo tells you “XDEBUG NOT LOADED AS ZEND EXTENSION” you did not include the .so as zend_extension (which is required, as mentioned above).
    xdebug.remote_enable must be set to 1 or on, it defaults to off.
    (i was confused because xdebug.remote_host defaults to localhost, xdebug.remote_port to 9000 if not set)

  26. […] 本来想用phpEclipse,那东西实在太慢,调个脚本程序,兴师动众的。网上说zend studio比较快。Eclipse因为习惯了,和前景看好,还有兴趣用,不太想用zend studio。总觉得应该有更简便的工具。果然在网上看到了用vim做前端的调试方案。主要参考了这篇文章完成了任务 (http://tech.blog.box.net/2007/06/20/how-to-debug-php-with-vim-and-xdebug-on-linux/) […]

  27. ruslanix says:

    Hi!
    I try this script for MS Windows.
    I have some problem to run this plugin.

    If interested here i describe some problem and solution:

    errors occurred because this script was written to linux.
    And on windows you should do some changes

    1. At vim startrup error: ‘Can’ find debugger.py’

      • put debugger.py to $VIMRUNTIME/plugin directory
    2. After starting debuggin, error : ‘can’t open session file’

      • go to line 442 at debugger.py and change self.sessfile to file suit for you.
    3. When press ‘Setp into, F2′, error: ‘wrong buffre name /….’

      • you must change in all lines code from getAttribute(’filename’)[7:] to getAttribute(’filename’)[8:]

    By;)

  28. […] Xdebug and VIM XDebug and Eclipse on Windows Debugging Drupal with XDebug Tracing PHP with Xdebug Debug PHP with VIM Debug Drupal with VIM Debug Symfony with VIM Debuggin PHP on […]

  29. […] there is. Sam Ghods tells you how. Posted by phpimpact Filed in PHP, Programming, […]

  30. […] traces, profiling and code coverage analysis. Debug clients are available in many PHP IDEs and even plugins so you can debug from everybody’s favourite editor vim. […]

  31. […] traces, profiling and code coverage analysis. Debug clients are available in many PHP IDEs and even plugins so you can debug from everybody’s favourite editor vim. […]

  32. alexander says:

    thanks

Leave a Reply