Troubleshooting ExpressionEngine
"Debugging." Photo credit: stock.xchng
How many times have you been working on a site and poof! something doesn't work the way you expected? For most developers this is just part of the process. There are some common ways to debug issues that are built right into ExpressionEngine. You just need to know how to use them. There are other things that aren't necessarily tools but rather features that might be missed causing errors. Let's dive in.
Aside: This article was originally published on my personal blog on December 18th, 2009. It's been updated with some additional methods along with EE2-specific changes. The original comments have also been migrated over.
My Troubleshooting Process
This is a quick run down of where my head typically goes when trying to debug something with ExpressionEngine. Some of these thoughts apply to things other than EE as well.
Dynamic="no"
At some point or another this one gets everyone from the newbie to the veteran. Dynamic="no" (formerly dynamic="off" in EE1) is a parameter used within the channel:entries tag pair that tells ExpressionEngine to ignore the URL when querying the database for results. By default EE reads your URL segments and bases the channel:entries results off of said segments. I personally think that this should function in the reverse order and that dynamic should be set to no by default. I find myself adding that parameter to many more channel tags than not. For a good video tutorial (runtime 2:51) on dynamic="no" visit Train-EE's Dynamic = Off Explained!
Template Debugging
Is something in your template ackin a fool? Well Template Debugging might do you some good. It breaks down different pieces of the template parsing and shows you what's happening and when. It's kind enough to slap an elapsed time next to each item as well. Here's an example of what you might see:
(0.000016) - Begin Template Processing - (0.000215) URI: (0.000226) Path.php Template: site/pages (0.000241) Retrieving Template (0.000273) Retrieving Template from Database: site/pages (0.001650) Template Found (0.002578) Retrieving Template from File (0.002923) Template Type: webpage (0.003035) Parsing Site Variables etc...
Note to Developers:
You can tap into what's displayed here. If you are writing a plugin or module for ExpressionEngine you can add lines to this to help your user see what happens and when. There is a function in the Template Parser class that allows you to add a line at a time. Here's a quick sample code:
<?php
// probably in your plugin constructor
$this->EE =& get_instance();
// log a message to the template debugger
$this->EE->TMPL->log_item("Your message goes here and can include ".$variables);
?>
Display Output Profiler
Say your template (design) is being parsed correctly and you don't have any obvious errors in your code but the results from some of your EE tags are not what you expected. You can turn on Display Output Profiler to see exactly what queries are being run and when. This is very helpful in certain scenarios but you will need to have a basic to moderate understanding of MySQL for it to really mean anything to you. It also helps to be familiar with the EE database tables and what is stored in them.
It can also be useful for displaying your config variables, GET and POST data along with some other goodies. If you haven't used the profiler you should check it out. It's pretty handy stuff. In the good ole days of EE 1.x it was simply "Display SQL Queries" but when EE entered adolescence it adopted CodeIgniter's Output Profiler.
Note that if you are using page/template caching you may be missing some queries. The templates that are being cached will not be running queries that they would otherwise need. So for debugging queries you will either need to turn off caching for a particular template or clear your cache frequently.
You can find settings for both Template Debugging and Display Output Profiler under Admin > System Preferences > Output and Debugging Preferences.
Debug Status
ExpressionEngine has a useful preference available to alter who sees PHP/database error messages on your site. You can set it to either show errors to Super Admins or to anyone (not recommended). You can also turn them off all together. Keep in mind that this is specific to php.ini settings and may require some PHP configuration before using. To see if you have error reporting turned on go to Admin > Utilities > PHP Info and search for display_errors.
The Debug Status option is also located under Admin > System Preferences > Output and Debugging Preferences.
White Page of Death
Say your EE site's front-end or Control Panel is completely white. You can't exactly get help from the Output Profiler or Template Debugging if the page doesn't even render anything. The ultimate "debug switch" can be found in your site's index.php files. If your white screen of death is on the front-end of your site then crack open that index.php file in your editor and look for this bit of code:
/* * -------------------------------------------------------------------- * ERROR REPORTING OVERRIDE * --------------------------------------------------------------------
Below that you'll see a paragraph explaining exactly what you're about to do. It's important to note that "[e]nabling this override can have security implications. Enable it only if you have a good reason to." So, what you'll want to do is change the value of $debug to 1. Your code would look like this:
$debug = 1;
If your white screen of death is on the Control Panel side of things you need to do the same thing described above - except with the system/index.php file or your masked CP file (which might be something like admin.php).
This will effectively "turn on" error reporting to everyone. I only use this locally because it often gives details on application and database structure in the error messages. Regardless, it is a very helpful tool if your page is rendering nothing at all.
Additional Processes
There are a few things I use often when troubleshooting items in ExpressionEngine that are not specific to EE but are basic PHP functions. Any of the following tips can apply to your PHP scripts.
.htaccess
Most CMSs I've had my hands on include some form of URL rewriting support. In a LAMP stack this often comes in the form of mod_rewrite within an .htaccess file. If you're experiencing strange URL behavior such as a redirect loop, extra or missing URL parameters etc - crack open your .htaccess file to see what's going on.
These .htaccess files affect their subdirectories as well. With that in mind, you should consider checking your current directory's .htaccess and its parent directories as well, if there are any. I typically start by completely commenting out the contents of the file. Then uncomment section-by-section after that.
print_r()
This is a PHP function that comes in very hand when trying to determine what is within an array or object. I learned a lot about the EE global objects in 1.6.x and the EE super object in 2.x using this function. Just run this in a PHP-enabled EE template and see what you have access to so easily:
<?php
$this->EE =& get_instance();
print_r($this->EE->input);
?>
I actually use this so often that I made a short TextMate snippet to automatically wrap this in <pre> tags for me to make the display vastly easier to read. If you aren't already using print_r() then it will quickly become your friend.
var_dump()
This function is actually quite similar to using print_r() except it spits our some additional information about the data. For example, the following code when using print_r() will look like each variable is identical:
<?php
$string = "1";
$integer = 1;
$array = array($string,$integer);
print_r($array);
?>
The above code should produce this:
Array
(
[0] => 1
[1] => 1
)
Those two values look pretty similar to me. But if they are, then why doesn't $string === $integer return TRUE? Take a look at it this way:
<?php
$string = "1";
$integer = 1;
$array = array($string,$integer);
var_dump($array);
?>
This time you should see this:
array(2) {
[0]=>
string(1) "1"
[1]=>
int(1)
}
This is much more beneficial because it not only shows us the values, but it shows us the type of data and the length of the data. It starts with array(2) which tells us that you are looking at an array with 2 items in it. Next we see the first key/value pair which is 0 => "1". It tells us that the item data type is a string, it contains 1 character and the value is "1". Next we have int(1) which is our second array item. It shows us that the item data type is an integer and the value is 1. If we just used print_r() we wouldn't have known any of these additional details about our data types and could possibly have gone crazy wondering why our conditional statement won't return what we think it should. So take var_dump() and put it in your pocket; save it for a rainy day. Or almost every day - depending on the work that you do.
When In Doubt
More often than not you will have some 3rd party add-ons at work in your templates (to some degree). It's important to keep in mind you could have either a native EE problem or a 3rd party problem at hand. Consider consulting the documentation of these add-ons before assuming the error is with ExpressionEngine itself.
Helpful steps:
- Verbally talk through your problem (sounds silly but it's quite effective)
- Try the troubleshooting steps in this article
- Seek help on EE forums or 3rd party support channel
- Ask on twitter (with the #eecms hash, of course)
- Consider sites like Stack Overflow for general PHP or server issues
Un-helpful steps:
- Bug the first person you see on AIM/Skype/gTalk without trying things yourself
- Complain on the EE forums without troubleshooting yourself
- Complain on a 3rd party dev's forums without troubleshooting yourself
- Complain on twitter
Additional Links
Beyond the suggested tips above you can check out the following links when trying to debug or troubleshoot your ExpressionEngine issues:
- Output and Debugging Preferences (official EE docs)
- Troubleshooting (official EE docs)
- Debugging Basics (Episode 30 of the EE Podcast)
That's All Folks
I hope this article helps give you a better idea of how you might troubleshoot some of your ExpressionEngine problems. These really are things I use on a daily basis and they are tremendously helpful.
Adam Wiggall on December 8th, 2009 8:28 pm
Erik,
Some great tips here, as you know I was digging around in the SQL queries earlier to find a problem. Tips like that are invaluable for troubleshooting.
And now I’ve worked out where the problem lies, I just need to work out a way to fix it…
Thanks,
Adam
p.s. Do you mind sharing that TM snippet with us
bjorn on December 9th, 2009 8:37 am
Agreed, great post Erik. I haven’t tried your toolbar yet, but I might just do that now :)
I had to tweet it :) http://twitter.com/codeignitee/status/6491247837
Erik Reagan on December 9th, 2009 12:10 pm
Thanks for the kind words Adam and Bjorn.
@adam, I’ve linked you up to my GitHub repo of a TextMate bundle of mine which include the print_r snippet I mentioned in the post. If anyone else is interested perhaps I will just make a post about it.
@bjorn, Thanks for the tweet. I’d love to hear your thoughts on the toolbar after you’ve had some time to use it :)
Pesche on December 10th, 2009 7:51 am
Nice writeup Erik!
One little thing thouigh: in PHP5, using references in general is deprecated (http://php.net/manual/en/language.references.php).
Erik Reagan on December 11th, 2009 11:46 pm
Thanks for the heads up about references Peter :)
Sean on February 11th, 2011 6:09 pm
Erik,
thanks for this article. Lots of good suggestions and a few that I didn’t know about. I particularly like your “unhelpful steps” which I may have been guilty of a couple of times.
Erik Reagan on February 11th, 2011 6:16 pm
Thanks Sean. Glad you found it useful.
BTW - I know about all of these steps because I’ve used them all at some point in the past. That includes the unhelpful ones too :p
Sean on February 11th, 2011 6:19 pm
Erik,
glad to see I’m not the only one. Actually this article is particularly useful to me since my rate of client work is inconsistent and I tend to forget some different ways to debug. Have bookmarked this on diigo - so hopefully I won’t forget again.
Ryan Battles on February 16th, 2011 12:26 am
Many times simply viewing the template debugging messages solves it for me. I have never tried those PHP snippets you mentioned, but will certainly have to return to this post and give them a go next time I get stuck. Thanks for sharing!
Jae Barclay on February 27th, 2011 2:54 am
Great article Erik (especially about the helpful / not helpful ways to bug). Sometime the errors are the simplest of things, such as:
- pulling an entry on a more/detail page in more than one place, where only one instance will show
- channel:entries tag has an invisible default limit of 100: you can only show the 101th+ entries by specifying a higher “limit” number (such as limit=“999”)
Thanks a bunch for the php snippet and the var_dump tips. Even after years of working with EE, there are always things that make you go, “aha”!
Erik Reagan on February 27th, 2011 8:26 am
Thanks, Jae.
Good point about the automatic limit of 100 in the channel:entries tag. I remember that getting me once. I was “running around” looking at entry dates, statuses etc and couldn’t figure out why the additional entries wouldn’t show up. Finally, when pulling up the Show SQL Queries debug tool (from the 1.x days) I noticed that the query had a limit of 100 applied to it.
Adam Khan on April 7th, 2011 9:53 pm
> Dynamic=“no”
This has gotten me a number of times, especially later in the day. My solution has been to use TextExpander to make “expw” into a shortcut for:
Then remove whatever’s not needed.
Nice write-up.
Gtalk on August 14th, 2011 9:25 pm
Thanks my friend for sharing such an interesting and valuable information to me :) It helping me for my project