
The pessimist sees difficulty in every opportunity. The optimist sees opportunity in every difficulty.
~ Winston Churchill.
Back in the days before Xdebug1 came to light, debugging PHP2 was pretty simple, like in C3, where you use print or var_dump and pray that the output tells you something useful. It worked, but it was slow, clumsy, and always left you with a codebase full of temporary print statements you had to remember to clean up.
Today, with improving tools and setup, PHP can now be debugged remotely with the help of ssh + xdebug. You get proper breakpoints, step through the code line by line, and inspect variables while the request is still running, all from the comfort of your own editor, even when the server lives on the other side of the world.
🔌 The Remote Port Forward
To do this, first you must connect to the remote development station where the PHP server is located (e.g. PHP direct dynamic server, Nginx, Apache HTTP):
ssh -R 9000:localhost:9000 username_goes_here@hostname_goes_here
The -R stands for return remote callback connection on SSH, on which server --(poll)--> host (xdebug server). What this does is forward the port from the remote machine back to your local workstation, so when Xdebug on the server wants to talk to your debugger, it reaches it through this tunnel as if it were a local connection.
⚙️ Configuring Xdebug on the Server
After running the remote port forwarding you will need to set up xdebug on the remote server, pointing it to the address where it should bind and listen. For my use case I’d point mine to the loopback address [IP_ADDRESS] (as I’d only use it for development purposes) on which we set up the remote port forwarding to listen to. Edit the php.ini file and at the xdebug configuration make it similar to the sample below:
[xdebug]
zend_extension="/usr/lib64/php/7.1/modules/xdebug.so"
xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.remote_host=[IP_ADDRESS]
xdebug.remote_port=9000
xdebug.remote_log=/tmp/xdebug_remote.log
xdebug.remote_connect_back=0
The most notable part in the config is the xdebug.remote_host and xdebug.remote_port, this is where xdebug would bind. The remote_log line is a quiet lifesaver too: if debugging mysteriously does not work, that log file will tell you exactly what went wrong instead of leaving you guessing.
🔄 Restart the Server
After all the changes have been done, just restart the server (e.g. for Apache HTTP running on CentOS):
service httpd restart
PHP reads its configuration at startup, so this step is not optional. Skip it and your carefully edited php.ini will be politely ignored until the next reboot.
⌨️ Point Your Editor at It
And at our workstation, with a PHP debugger extension in our editor, we would just point it to [IP_ADDRESS]:9000. That’s all, now we can debug PHP remotely.
🧡🧡🧡🧡🧡
🧠 Final Thoughts
Setting this up once saves you hours down the road. The next time a remote server misbehaves in a way that print statements cannot explain, you will be glad the tunnel exists: run the ssh command, let your editor connect, and step through the mystery line by line.
Hope you guys enjoyed this article!
- Xdebug is a PHP extension which provides debugging and profiling capabilities. It uses the DBGp debugging protocol. ↩︎
- PHP is a general-purpose programming language originally designed for web development. It was originally created by Rasmus Lerdorf in 1994; the PHP reference implementation is now produced by The PHP Group. ↩︎
- C is a general-purpose, procedural computer programming language supporting structured programming, lexical variable scope, and recursion, while a static type system prevents unintended operations. ↩︎