Hướng dẫn Debug Drupal PHP trong Vim với Vdebug

Vim as a Xdebug client

I know quite a few developers that love Vim but think they have to use an IDE to be able to debug their applications. In this post I will show you how to set up Vim as a Xdebug client.

>> Tuyệt vời với Drupal 8 Through Adoption - Drupal 8

>> Xây dựng Drupal 8 trên VirtualBox và Vagrant trong Windows

>> Drupal : Hướng dẫn tạo Content Builder sử dụng Paragraphs

The Vdebug plugin for Vim provides a way to do debugging inside Vim using the tools that Vim provides to great advantage. As the project page says,

Vdebug is a new, fast, powerful debugger client for Vim. It's multi-language, and has been tested with PHP, Python, Ruby, Perl, Tcl and NodeJS. It interfaces with any debugger that faithfully uses the DBGP protocol, such as Xdebug for PHP.

In this post we will focus on PHP, and more specifically, Drupal.

XDEBUG

The first step we must take is to confirm you have Xdebug working in your application. If you don't have Xdebug installed head over to their site and follow the installation guide. You don't have to do anything special in order to use Vdebug with your PHP application. If you are currently using another debugging client like the one built into PHPStorm you shouldn't have to change anything in your PHP configuration. But, for sake of completeness here is an example Xdebug configuration we (Mediacurrent) use on all of our projects. We have standardized our local development work on the great Drupal VM project.

[XDebug]
zend_extension="/usr/lib/php5/modules/xdebug.so"
xdebug.coverage_enable=0
xdebug.default_enable=0
xdebug.remote_enable=1
xdebug.remote_connect_back=1
xdebug.remote_host=10.0.2.2
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_log=/tmp/xdebug.log
xdebug.remote_autostart=false
xdebug.idekey="PHPSTORM"
xdebug.max_nesting_level=256

XDEBUG HELPER FOR CHROME

The next step is to set up your browser to allow you to easily enable and disable Xdebug. To do this, I use the Xdebug helper for Chrome. It's much easier than setting up POST variables and cookies for each browser session. You will want to make sure your `idekey` is set to match what you are using in xdebug on the server. In my case, that is PHPSTORM.

VDEBUG FEATURES

Now that we have Xdebug all squared away, let's learn about Vdebug. Just what can Vdebug allow you to do?

  • Set and toggle breakpoints.
  • Step through your code line by line.
  • Step over functions and methods.
  • Step into and out of functions and methods.
  • Run the application to the cursor.
  • Evaluate variables under the cursor at run time.
  • Navigate objects and arrays.
  • Evaluate code and display the result.

INSTALLING VDEBUG

If you don't already use a plugin manager for Vim I recommend you check out Vundle, but the way you install Vdebug has no affect on how you use it. I recommend that you follow the installation instructions on the Vdebug project page to get it set up.

DEFAULT KEYBINDINGS

For your convenience, I have listed the default key bindings for Vdebug below (I have changed the defaults in my own vimrc since I find them to be somewhat difficult to remember).

<F5>: start/run (to next breakpoint/end of script)
<F2>: step over
<F3>: step into
<F4>: step out
<F6>: stop debugging (kills script)
<F7>: detach script from debugger
<F9>: run to cursor
<F10>: toggle line breakpoint
<F11>: show context variables (e.g. after "eval")
<F12>: evaluate variable under cursor
:Breakpoint <type> <args>: set a breakpoint of any type (see :help VdebugBreakpoints)
:VdebugEval <code>: evaluate some code and display the result
<Leader>e: evaluate the expression under visual highlight and display the result

USING VDEBUG

Note: during this screen cast I am using my own key bindings which I outline later in this post.

DEBUGGING DRUPAL IN A VIRTUAL MACHINE

If you only ever debug using your machine's native version of PHP you can skip this step. But if you need to connect to a server running your code (Vagrant or Remote), you will need to do one more step to set up Vdebug. You need to tell Vdebug where your files are on your local file system and the server's files system. The reason you need to do this is because the file paths on your local machine and the server are most likely different. Let's look at an example.

" Mapping '/remote/path' : '/local/path'
let g:vdebug_options['path_maps'] = {
      \  '/var/www/drupalvm/web' : '/Users/kepford/Sites/someproject/web',
      \  '/home/vagrant/docroot' : '/Users/kepford/Sites/anotherproject/docroot'
      \}

The first portion of the mapping is for the remote path /var/www/drupalvm/web. The second is for the local path /Users/kepford/Sites/someproject/web. That's all you have to do for remote debugging.

CUSTOMIZING VDEBUG

Now that we have everything set up let's talk about custom configuration. The default keybindings that ship with Vdebug may not suit your preferences. Personally, I try to come up with mnemonics for each Vim command and struggle to remember the correct function keys for Vdebug. The good news is it's easy to override the defaults in your .vimrc file. Here's an example of what I have done with my defaults.

let g:vdebug_keymap = {
\    "run" : "<Leader>/",
\    "run_to_cursor" : "<Down>",
\    "step_over" : "<Up>",
\    "step_into" : "<Left>",
\    "step_out" : "<Right>",
\    "close" : "q",
\    "detach" : "<F7>",
\    "set_breakpoint" : "<Leader>s",
\    "eval_visual" : "<Leader>e"
\}

Note: I have my <Leader> key set to be the space bar and find this is very productive.

You may not like my key mappings but they work for me. The rest of my configuration is fairly straight forward.

" Allows Vdebug to bind to all interfaces.
let g:vdebug_options = {}

" Stops execution at the first line.
let g:vdebug_options['break_on_open'] = 1
let g:vdebug_options['max_children'] = 128

" Use the compact window layout.
let g:vdebug_options['watch_window_style'] = 'compact'

" Because it's the company default.
let g:vdebug_options['ide_key'] = 'PHPSTORM'


" Need to set as empty for this to work with Vagrant boxes.
let g:vdebug_options['server'] = ""

DEBUGGING THE DEBUGGER

If you encounter a problem getting Vdebug to work it's likely that you need to change a setting. But before you do that you should turn on debugging. Run the follow two commands to dump the output of the Vdebug log to a file.

:VdebugOpt debug_file ~/vdebug.log
:VdebugOpt debug_file_level 2

Then tail the output of this file like so, tail -f ~/vdebug.log as you start Vdebug and try to use it.

MORE READING

As with any good Vim plugin you can learn a lot more about how to use it by reading the help documentation at :help Vdebug