Remote PHP Debugging with Xdebug

Introduction

In our previous posts, we discussed how to use some tools to explore and debug legacy code. This blog post will explore one of these tools that I personally use quite often in depth: Xdebug and Remote Debugging.

We’ll explore the installation, the required settings tweaks, and some basic tools and workflows to get you started. The least fun and hardest part of this whole process is the installation.

Having xdebug up and running will speed up your code investigations and will really help you dig into troublesome code. It will also give you the best insight into code you aren’t familiar with works without resorting to die statements and var_dumps for small windows.

Development Only

Please only install this on your development and staging environments! Do not install this on any public facing server!

Remote Debugging

I want to take a minute and explain the concept of remote debugging with Xdebug. Until a few years ago, I would install XDebug only to get the “pretty error printing” features. While these features allowed some better control over how I was viewing errors and my var_dump results, it really added nothing I critically needed. Remote debugging now makes XDebug a short list of ‘need to install’ things when setting up a new environment.

Xdebug offers mechanisms to allow you to set breakpoints in your code to stop it’s execution and view the current state. This means you can say “stop here and let me take a look around at what the code is doing at this moment” on the server itself. You actually connect to the server and can poke around, set some conditional break points (where you stop execution when a variable is set to a certain value) and even evaluate some raw PHP on the server given certain conditions.

To accomplish this, you must connect a debugging tool to your server with a specified and exposed port and talk to it using a protocol provided by XDebug. Your debugger is the tool you use on your machine, XDebug is the tool/port/settings collection you use to connect to your server.

If this sounds like the basic IDE debugging tools you have used with other languages like C++ and JAVA (and also like something overcomplicated for being such a normal feature for other development stacks), it should. It’s pretty much the same thing. The biggest difference here is that this was not a widely used debugging method for hosted PHP. I’d like to help change that with this blog post.

Installing the Xdebug Extension

The xdebug project and github page offer some installation instructions that feel woefully lacking. Also, they offer little advice tailored to individual setups and environments. I’ll try and provide some examples of common installation methods.

Please note that these methods assume you are installing on the same server you host your development environment that serves the PHP code you wish to debug. This means, if you are running a vagrant box or docker container to host your code, install xdebug on this server instance. If you host your locally code on the same machine you are edit and maintain the code on, install xdebug on this machine. See the section above for some clarification on remote debugging.

All of these instruction assume you have administrator access and some level of comfortability with the *unix command line. If you do have access to your server in this capacity, or you are not comfortable with running these commands, you might want to find a grown up to help you.

pecl / pear

You can install Xdebug extension with the pecl tool and then tweak your php.ini file to include the installed extension. The official docs recommend this route first actually. The installation instructions are the same with the pear tool as they are for pecl. I have found this is the easiest installation method if you are running your server on a MacOS environment.

After you are sure you have pecl installed, run this command on your command line.

pecl install xdebug

apt-get / yum

If you are running your server on an Ubuntu/Debian/CentOS machine, you can install the xdebug with your specific package manager.

sudo apt-get install php5-xdebug

or

yum install php5-xdebug

Homebrew

This is a method I have never tried personally but I know there are some recipes specifically for installing xdebug with homebrew.

From what I read, you will need to add the homebrew-php repository and install this from the command line as well. Check out this repo link for more information.

Compiling it yourself

Another method I have never tried personally, but I know its possible. If you are want to do this yourself, you might be beyond the scope of this post. I’ll just point you to the project page for the most up to date information.

Update your php.ini file

Find your newly installed php extension and add this line to your php.ini file

zend_extension=“/usr/local/php/modules/xdebug.so”

Replace the “xdebug.so” file with whatever your tool installed. It’s also safe to create a symlink with the filename “xdebug.so” as well. If you have trouble finding this file, try the following command to find the extension file:

find / -name ’*xdebug*.so’ 2> /dev/null

Verifying your XDebug Installation

Restart apache and create a test file called test.php with the following lines of code and load it into your browser:

<?php

phpinfo();

Search for “xdebug” and you should see something like this in your browser:

image

If you see a line that looks like the one highlighted above, congrats, you have installed xdebug!

Port Forwarding

You will need to expose some ports on your server to allow connections from your debugging client. How you accomplish this will certainly depend on your individual environment setup, but I would like to note this to save you the time I lost trying to find out why I could not connect.

And we will explain the port you will need to be expose and forward in this next section…

Xdebug INI Settings

Here are some of the INI settings you will need to update in order to enable remote connections. These settings will be found in your php.ini file, or a possible xdebug.ini file if one was created by your install method.

  • xdebug.remote_host
    • This setting allows you to specify an address where you debugging client is connecting from.
    • In most cases, this will be set to “localhost”, but may differ in your development environment.
    • This setting is ignored if xdebug.remote_connect_back is set to TRUE. See more info below.
  • xdebug.remote_autostart
    • This setting enables remote debugging, turn this on!
  • xdebug.remote_port
    • This setting allows you to specify a port for your debug client to connect to the remote server with. You will need this value when configuring your remote debugging tool.
    • This is typically set to 9000 but you can update this to any port that isn’t being used if you feel contrary.
  • xdebug.var_display_max_children
    • This setting allows you to specify the amount of array children and object’s properties are shown when you use a var_dump or use your debugging client’s function trace tool.
    • By default this is set to 128, but you can set it to -1 if you want to remove the limit entirely.
  • xdebug.var_display_max_data
    • Like var_display_max_children, this setting allows you to set a  maximum string length that is shown when variables are displayed in var_dumps or function traces.
    • By default this is set to 128, but you can set it to -1 if you want to remove the limit entirely.
  • xdebug.var_display_max_depth
    • Another setting that allows you to set a limit when using var_dump or function tracing, but this one sets the nested levels of array elements and object properties displayed.
    • By default, this is set to 128, but again if you live dangerously you can remove the limit entirely and set it to -1.
  • xdebug.scream
    • Setting this value to true will disable the @ (the “shut up”) operator entirely.
    • This is super useful when you find out when you predecessor was just hiding a critical error behind the @ operator and you can finally go to be because you found the elusive notice showing the variable was never set in the first place and you had no idea and thats why you can’t get the page to load when you don’t have a cookie set in IE 9.
  • xdebug.remote_connect_back
    • Setting this value to true will allow you to connect and attach a remote debugging client to your server from any address.
    • This setting is great for shared development environments but is quite dangerous since it will just allow anyone to connect who tries. YES, anyone.
    • Also of note, this will override the xdebug.remote_host setting.

Remote Debugging Tools

Editors

PHPStorm & SublimeText

While I personally like to use the stand alone tools, I do know a lot of people who prefer to use these editors to remote debug.

While I’m sure a cursory google search can lead you to some better instructions on how to install and configure these tools, I thought it was worth mentioning since a lot of people use these tools and they offer the remote debugging tools you might want to use.

Stand Alone Tools & Helpers

MacGDBp

This is a tool I use on an almost daily basis. Its relatively small and lightweight, and gets out of the way when I am done. I also mentioned it in our last blog post. I do need to note that this tool does not seem to be updated frequently and occasionally crashes without warning. That being said, I still highly recommend it.

Chrome Xdebug Enabler

This is a simple chrome extension that allows you to toggle the xdebug remote debugging cookie for a given URL. This is great to quickly start and stop a remote debugging session.

It’s pretty much an unobtrusive button that lives in chrome. I would install it now if I were you.

Conclusion

I barely touched the surface of remote debugging using xdebug, but I hope I inspired you to install and configure it now. Stop using var_dump and die statements and debug like a grown up!

Legacy Code Evaluation Part 2 – Back End Code Evaluation and Tools

Intro

All of us will encounter legacy code, and most of us will ‘inherit’ code to maintain. In our first post on legacy code, we talked about getting the things you need to start working on a project. In this post, we will talk about how you can evaluate the backend code you will most likely have to start digging in to start new features or squashing bugs.

While you will encounter a significant amount of UX or front-end issues when starting on a new project, you are also just as likely to have to track an issue to the underlying backend code. The backend not only creates the foundation for your web app but its also the last line of defense for your back end code. At minimum issues on the backend will cause confusing results or headaches. At worst, issues on the backend will expose some of the most vital parts of your webapp to exploits.

Most backend code is the result of a lot of hours and hard work; it can be extremely confusing to wrap your head around the basic concepts let alone the deeper portions of the code. We’ll discuss some basic patterns and explain some of the tools we use to explore code, PHP code in particular, when we take on a project with some ‘baggage’.

Strategies

I like to split the application into small semantic sections. You can either break an application down into ‘workflows’, the actions a user may perform with an application; or as ‘roles’, things a particular actor will use a web app for. While this may sound like a very high level activity for inspecting back end code I think its crucial for understanding the application itself.

Once you have split the code into sections, trace the entire workflow. Follow the code from the beggining of an action to the resulting output. Tracing through the code will allow you to completely understand it.

Debugging and Tracing Tools

Xdebug

This is one of my favorite tools and is the first thing I install when I set up a new environment. Not only does this give me much easier to read error outputs, but it also gives you some great tools for interactive debugging. Seriously, if you do nothing else I suggest, at least install xdebug.

Remote Interactive Debugging – MacGDBp & chrome-xdebug-enabler

Interactive debugging is the best tool for finding that super stubborn bug or finding out why something isnt working as you expect. With a remote interactive debugger you can set break points and view exactly what the code is doing at a given point in time. You can actually inspect a variable value and watch it change as you step through the lines of code. This is something you should get excited about. Check out the screenshot below to see this in action with an example Erdiko project:

I use MacGDBp, a Cocoa based debugging tool that allows you to set break points and view the code when you set break points. I’ve been told that PHPStorm and even Sublime have some interactive debugging tools, I have not used those. MacGDBp is a bit dated, and I think almost abandonware, but it is still an indispensible tool in my aresenal. Check out the MacGDBp project docs for more info about the feature set and how to install it.

Personally, I would recommend using MacGDBp along with xdebug and the chrome extension ’chrome-xdebug-enabler’ to interact with your debugger. Using this extension you can conditionally turn the debugging off and on as you wish when refreshing the page.

I should note that while I personally use MacGDBp with vim, many other editors also include some remote debugging tools. PHPStorm has this functionality built in, but there are plugins for SublimeText and other full editors. We will explore those in a later post.

PHPLint and PHPCodesniffer

There are two great tools for getting some high level information about a PHP codebase: PHPLint and PHPCodesniffer.

PHPCodesniffer evaluates code based on a provided set of rules and standards and outputs a report that can give you a good idea of how ‘bad’ things look under the hood. It’s actually two tools: phpcs and phpcbf. phpcs evaluates the code, phpcbf attempts to fix the code. Personally, I like to use some discretion when tweaking code, so I would reccomend using phpcbf sparingly.

PHPLint is another tool, very similar to PHPCS that also outputs information on a code base based on rules and validation sets. This one is also very useful for generating user docs based on docblocks. This can be EXTREMELY useful when you need to collect a lot of information about a large codebase and create some baseline documentation for your team.

Unit Testing

Unit testing is often touted as the best prevention of introducing new bugs and finding conflicting code. I would also like to note, most people ignore the fact that introducing unit testing to legacy code is a painful process. Code written without testing in mind can often be a pain to manage dependencies and ‘magically’ required code.

This is a topic that actually deserves its own blog post, but I do want to mention it in this one.

… to be continued

In my next post, ill include some instructions on how to install xdebug on your local *nix development environment.

A New Framework Architecture for 2016

Why a new architecture?

PHP is the most popular language on the net and has a wide array of frameworks, apps and packages available.  Most of the best ones are open source, free or have a freely available version of their paid app.

That being said, it’s only more recent that the frameworks are being made, or attempts are made, to make them work together as components.  I thinks its about time to rethink or re-imagine how a developer or architect can create complex systems in an incremental and meaningful way.

I spoke a bit about the history and features of PHP previously.  Folks like Facebook and Baidu use it extensively. Some of the PHP platforms that are widely adopted are Drupal, WordPress, Magento, Joomla, Media Wiki, Symfony, Laravel, and Yii.  All have considerable user bases and impressive feature sets.  They all however, have very different conventions, coding styles and theming styles.

Speaking of theming, the way developers create a UI these days is dramatically different than how it was done in the past.  Browsers are more powerful and devices are more diverse.  JavaScript is much more powerful and more uniformly supported than it was a decade ago when PHP 5 came out (don’t forget about the V8 engine too).

  • Theming: Not everything has to be PHP anymore.  We now have
    • Bootstrap, & Material
    • Pre-compiling theme & components
      • Less/Sass
      • Gulp, bower, & grunt composition and code prep
    • Powerful JS frameworks and libraries: Angular, React, & more
      • Many more options than just jQuery these days

What’s missing from existing frameworks

  • Modularity
    • Some frameworks handle it well, but often the modularity is very limited to a smaller ecosystem, or at least an isolated ecosystem.
  • Composibility
    • Things are too often configured (db and config file) and not composed.  That is very convenient, but leads to slow production code and is more limited than a composable system
  • Security
    • Code should be outside the web root
    • Should work with and without a reverse proxy
    • Protect against common attacks
  • Models / ORM
    • The framework should work with any composer based (or modular) ORM
      • With so many rich ORMs and data connection tools available I don’t believe the framework should be relegated to only one ORM or model paradigm
      • Different scenarios call for different model approaches.  How can the framework facilitate the right data tool for the job?
  • Mashability
    • Create components that can easily be used together
    • Easy to add to any framework including erdiko
      • Leverage more code across and between frameworks
        • e.g. Use Eloquent in Slimphp
  • Routing
    • Symfony Request & Response
    • Symfony Router
    • Easy Compiled Routes
      • PhpMatcherDumper
    • Via plugins
      • Database routes (cms content)
      • Application specific routes
        • e.g. Magento, WordPress, Drupal
  • Server Automation
    • Work well with containers, modern deployments and popular coding workflows

The Developer / Architect paradox

This does however have a downside and that is what I call the developer / architect paradox.  This is developers wanting a complete solution and picking a tool that gets them 80% of the way there very quickly but they struggle with the 20% and have to make too many sacrifices and concessions to make the full system work.