Recently I’ve had several discussions with colleagues asking me for the debugging practices that I use. I try to constantly enhance my workflow, resources and improve the quality of my work by speeding up the process of narrowing down the possible reasons for a bug or a feature limitation. Speaking WordPress-wise, I’ll list a couple of things that I consider important. Some of them are more than obvious, but somehow people misuse them or forget about them at a moment of crisis (so to speak).
Before you start:Ā always do backups. Debug your web application locally, test properly and ensure that everything is on set before deploying to the real server. Best practices teach that a local server -> staging/dev server -> production server is a good setup to prevent the obvious error of hitting the live website.
Environment
I’ve been using plain text editors (vim included) for a while, but usually only for remote/small changes. I rely on a IDE for better control over the codebase and the relations. I’m anĀ EclipseĀ user (naturally evolved after several years in the Java world) but you could also check out NetBeans, Sublime, PhpStorm, Komodo or anything else with more capabilities. Using an IDE helps you to set up an easy connection between the codebase and a version control, debugger, (S)FTP and use a number of function suggestions and PHPDoc comments while developing and browsing the code. XdebugĀ or the Zend debugger are also a crucial part. Debugging with echo orĀ var_dumpĀ (orĀ console.log/alert) is a quickie for one-liners, but a serious workflow iteration processing requires a debugger.
I have an article about settingĀ Eclipse with Xdebug for Linux. I’m also usingĀ Chrome. Safari or Firefox will do the trick too, and for some bugs you need to run several browsers and check if there is a browser-specific bug. For some browser-app attempts such as IE you could nail a large variety of specifics due to their boxing model or JavaScript unique interpretation specifics.
WordPress setup
I’ve been using a number of separate plugins, most of which are already listed on theĀ DeveloperĀ plugin byĀ Automattic, along with other best practices. It reminds you about settingĀ WP_DEBUGĀ and other constants in your wp-config file, as well as install environment testing plugins. In addition to the plugins listed over there, I you may also find the following useful:
- Ā Hook Sniffer,
- P3 Profiler
- WordPress ConsoleĀ (orĀ WP-Cli).
Workflow
Scribu has made a good job of outlining the workflow for troubleshooting. You need to limit the options for a bug to happen. Normally it narrows down to 2 steps, iterated and expressed depending on the scenario:
- disable plugins one by one and see if one of the plugins acts differently on the site when on/off
- switch the theme
Sooner or later the problem disappears when plugins are disabled or the theme is gone. If that’s not the case, you should consider whether anything you have done directly on the database (custom changes) or the file structure (like manually editing WP-files or updating the core) is causing the issue. Sometimes WordPress core updates introduce new changes andĀ deprecatesĀ existing functions so a theme/plugin could be affected by that.
Once you have figured out what is causing the problem, you will have to find the reason for the bug.
Plugins
- See if the plugin isĀ dependentĀ on another plugin or your theme. There might be a conflicting PHP function or a JavaScript call that is incompatible with a theme/another plugin or not working anymore.
- Try to find aĀ repeatable contextĀ for the action, like a specific page where it occurs, or a number of pages. Find out if it happens in the backend (admin area), the frontend or both.
- See if you could find any errors in the logging plugins or theĀ error_logĀ file – they usually come up with a stacktrace telling you the origin of the error including a filename and a line number. If you happen to narrow the context, you would be able to find a common problem area – a piece of code that exists in the problematic pages and not in all the others. It will help you read fewer lines of code and debug a smaller chunk of the entire pack.
- For PHP errors, make sure you’re keeping up to date with yourĀ code style and conventions. Double check your functions don’t reappear (name collision) by being registered from another/plugin or a theme.
- Use prefixes or better OOP classes with a proper hierarchy (even namespaces!).
- Make sure your imports are included in theĀ right order. Do you register everything on the correct hook? Some actions such as script embedding should be registered on the right hook depending on the context.
- If you need frontend scripts, do useĀ wp_enqueue_scripts. If you wonder why is the admin looking clumsy, go forĀ admin_enqueue_scripts.
- If you have ajax calls, make sure they’re registered properly, withĀ WP AJAX hooks, passing the action properly. Also, some data might be lost due to the actual request, so just keep that in mind (it’s running in a different context, different time, so the environment could vary depending on that).
- Go through the plugin core andĀ beware of automagic. Some plugins try to run the principle of ‘convention over configuration’, which means that the configuration could be omitted if you follow a specific guidelines. It’s a common thing for frameworks such as Django or Rails-alike projects, keeping the same naming convention (files, functions) and directory structure for placing files. There is no verbose code stating that something is loaded – it just if it is named like that.
- A similar approach from the WordPress context is the templating structure – you haveĀ page.phpĀ that covers all pages,Ā index.php,Ā archive.phpĀ and so on. IfĀ archive.phpĀ is missing, it would fallback toĀ index.php. It’s not obvious, you just need to know the hierarchy and the chain of invocations. Some plugins define extra routes, additional context paths, AJAX rerouters and so on that make things complex.
Themes
Themes have a good process for a proper and painless interaction with WordPress core. However, some theme authors intentionally (or rather not) include custom implementations for their specific scenario that doesn’t behave well with all common cases. A common example is usingĀ timthumbĀ for image management – not only is it insecure and heavy, but it’s inflexible.
Knowing the template hierarchy, try the following:
- See if the template you’re after is actually the one running the code that’s broken.
- Beware of actions and filters that might be defined inĀ functions.phpĀ or in a third party plugin that could ruin your straightforward thinking.
- If data is not displayed at all (or a wrong data), check your query.
- Avoid usingĀ get_postsĀ orĀ query_postsĀ in a complex environment (or ever), better use a customĀ WP_QueryĀ query and reset the postdata at the end not to interfere with other listings.
- Debug your query calls and check the output SQL code generated.
- If there is a styling problem, it’s most likely a CSS definition. The correct order of CSS statements is important, usually the latter overrides the former. However CSS selectors have priority, such as – IDs are with a higher priority than just classes, so keep that in mind (even if a . call is below, the # call might be prioritized higher).
- See if theĀ correct stylesheetĀ is applied on the specific page and confirm that nothing is overriding it.
- JavaScript could be the cause of the styling bug or a functional one (lack of styling,Ā improper dropdown menu behavior, wrong AJAX request).
- Check yourĀ browser consoleĀ for JavaScript errors, usually at the bottom right corner. If $ is not found/evaluated, then you need to
- 1) enqueueĀ jQueryĀ (justĀ wp_enqueue_script(‘jquery’)Ā inĀ wp_enqueue_scriptsĀ hook call)
- 2) use jQuery before you define the alias. Prototype is run first and the dollar sign isn’t automatically applied to a jQuery call.
- See if the JavaScript in question is included properly, that there are no conflicts (no browser errors) and the event is fired at the proper selector. You could try running it on specific IDs or classes and console.log the activity, just to double check that it runs. If a script is terminated at any point, it’s most likely that the actions below are going to be canceled until further notice (read as: until the developer fixes the problem).
Servers
For Apache and nginx there are so many configurations that could make a difference.
- If you see 5xx errors, double check your server config first with a sample file as proof of concept and then proceed to inspecting your code for anything that could lead to misunderstanding with the server configuration.
- Verify yourĀ .htaccessĀ file in your plugin folder. There is a default one distributed with WordPress, unless you use caching plugins (or automate the caching) there is usually no reason to touch it.
- Check out yourĀ virtual hostsĀ in the server config. Domain names could be linked to the wrong IP/port sequence or folder, or the directory could not be writeable.
- If pretty permalinks are not working, have you gotĀ mod_rewriteĀ enabled?
- Some memory problems could be solved by increasing the PHP memory limit. You could try (in this order):Ā wp-config.php,Ā php.iniĀ orĀ .htaccessĀ (you might have your own preferences).Ā There are different configurations to change: server (PHP) memory, file upload size/timeout time and so on, for different activities.
Websites
Google is your best friend. Use it. If you don’t know how, it’s time to learn. And no, it’s not always straightforward. You need to learn how to select the proper phrase for searching (think about the results you’re trying to find) and eventually limit the results by theĀ advanced filters, like: limit by location, by date, use some wildcard like site:Ā intitle:Ā inurl:Ā filetype:Ā or anything that could help you limit the billions of results. StackOverflowĀ and theĀ WordPress StackExchangeĀ are super helpful. Don’t forget theĀ WordPress.org forums nettuts+,Ā WPCandyĀ or other WP-specific sources might help for WP-related troubles.