How to Debug PHP with Vim and XDebug on Linux
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.

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).

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!]









Thanks, this looks very interesting, but the link to ‘DBGp client script’ doesn’t work.
June 26th, 2007 at 6:10 pm
Thanks! This has been fixed.
June 26th, 2007 at 6:15 pm
[...] how-to-debug-php-with-vim-and-xdebug-on-linux/ [...]
July 18th, 2007 at 2:03 am
[...] ???? [...]
July 19th, 2007 at 9:13 pm
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
August 1st, 2007 at 1:49 pm
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.
August 1st, 2007 at 1:55 pm
thank you for keeping the xdebug vim script alive!
August 9th, 2007 at 8:56 am
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
August 10th, 2007 at 4:23 am
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!
September 10th, 2007 at 10:00 am
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
September 30th, 2007 at 10:52 am
Box.net: How to Debug PHP with Vim and XDebug on Linux…
Curt Zirzow has pointed out a cool article on the Box.net ……
November 7th, 2007 at 9:46 am
[...] Zirzow has pointed out a cool article on the Box.net website about debugging your PHP applications with a combination of Vim and XDebug [...]
November 7th, 2007 at 1:59 pm
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?
November 7th, 2007 at 3:32 pm
[...] 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 [...]
November 7th, 2007 at 4:58 pm
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.
November 8th, 2007 at 2:59 am
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.
November 8th, 2007 at 11:27 am
[...] 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 [...]
November 9th, 2007 at 10:41 am
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.
November 9th, 2007 at 11:41 am
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
November 14th, 2007 at 11:52 pm
The webserver and the machine I’m typing on are two difference machines. Is that a problem?
November 15th, 2007 at 2:59 am
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!
November 15th, 2007 at 4:25 am
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
November 15th, 2007 at 5:26 am
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
but the watch window says
.
November 15th, 2007 at 5:31 am
re the keys: earlier. I “meant” to talk about the script using
Leader d*, but my “html tags” were stripped:
gav
November 15th, 2007 at 5:33 am
[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)
November 20th, 2007 at 9:03 am
[...] ????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/? [...]
November 30th, 2007 at 9:46 am
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
At vim startrup error: ‘Can’ find debugger.py’
After starting debuggin, error : ‘can’t open session file’
When press ‘Setp into, F2′, error: ‘wrong buffre name /….’
By;)
February 2nd, 2008 at 4:34 pm
[...] 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 [...]
February 6th, 2008 at 10:56 am
[...] there is. Sam Ghods tells you how. Posted by phpimpact Filed in PHP, Programming, [...]
March 4th, 2008 at 5:40 pm
[...] 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. [...]
March 20th, 2008 at 8:02 pm
[...] 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. [...]
March 21st, 2008 at 1:16 am
thanks
April 26th, 2008 at 3:33 am
[...] Ref. http://2bits.com/articles/using-vim-and-xdebug-dbgp-for-debugging-drupal-or-any-php-application.html How do debug php with vim and xdebug on linux [...]
May 14th, 2008 at 1:45 am
Great article and great plugin. Thanks
I am getting an error when opening files with non-ascii characters in their paths. When opening (after F5 and refreshing browser) I get a E499 vim error (Empty file name).
The problem is that vim tries to open a file with urlencoded name (’my%20file’), which obviously does not exist.
I’ve been able to replace %20 for ‘ ‘ (escaped white character).
(Add file = file.replace(’%20′,’ ‘) at handle_init method (line 794) in debugger.py)
But (due to my lack of Python knowledge) I haven’t been able to replace other non-ascii characters (Spanish accented words áéíóú…). Same strategy (file = file.replace(’%C3%A1′, ‘á’) produces a UnicodeDecodeError in Python.
Does anybody have the same problem? Any idea how to proceed?
Thanks
June 10th, 2008 at 12:17 pm
You’d probably be better off just doing:
CFLAGS=”-D FEAT_SIGNS” ./configure –enable-pythoninterp
instead of messing with the source code to enable the FEAT_SIGNS macro.
June 10th, 2008 at 5:35 pm