The Complete Guide To Magento Debugging

How to Debug Magento

Integration of new solutions into different systems can become a headache without the knowledge of correct debugging.  In case of Magento, such simple constructions as print_r() or var_dump() , var_export() don’t work. Because of heavyweight constructions, you need to investigate the new effective ways to find intermediate values or broken places. Fortunately, there are a lot of tools and methods designed to turn the debugging into a developer friendly process.

Xdebug

To make the debugging more handy, you need the improved development environment. Xdebug is a must-have PHP extension designed for profiling and debugging. With the help of Xdebug, you can set breakpoints in your code and stop a PHP interpreter on them with ease. It is necessary for viewing app data on every executed line. Such IDEs as NetBeans, Eclipse, PHPStorm, Aptana and many others support the integration with xdebug. By using xdebug, you also get the ability not to use ‘echoing’ variables approach. As a result, the debugging of Magento objects is much easier and faster.

The major debugging methods

If you need to debug something on a remote system and has only SSH and tools of command line, you can use Zend_Debug class of Zend Framework. It contains a function, that works the same as var_dump. Zend_Debug::dump() is a static method, that returns information about an expression or prints it:

The $var argument is used to identify the variable or expression about which Zend-Debug method shows the information. The $label is a string prepended to the output. The argument is useful in a case of multiple variables on a given screen. The $echo is used to specify whether the method output is echoed or not. In general, the method plays a role of a wrapper for var_dump(), but extends its functionality a bit.

For the debugging on the environment working in the production mode, there are a few ways to hide the debug activity. First of all, you can restrict the output of debug info by your IP:

 Mage::log() method is another solution, which is a little bit more intelligent. It requires the use of logging system for debugging. Mage::log() is declared here: app/Mage.php. The method inludes 4 parameters:

 The $message is used to specifies the string required to be outputted into a file. The $level defines one of eight log levels of a debug message:

 To threat your debug message as a “DEBUG level message“, you have to specify ‘0’ as a parameters value. You can use integer values from 0 to 7 or their equivalent constants (Zend_Log::CRIT, Zend_Log::DEBUG etc..). In the second case, the code will be more readable.

The $file contains a log file relative path. Magento uses the var/log directory to put logs there. To place the log file in this directory, you have to pass a filename as a parameter. In its turn, $forceLog allows you to use Mage::log in a case, when the logging is disabled from the configurations. If you are going to implement a non-regular instant debugging, you just have to pass $forceLog. The complete structure:

Zend_Debug::dump() is used for variable dumping. To disable output, you should pass the third parameter as false. As a result, debug method will return the string written into a log. The path of the log is ‘product_debug.log’, the placement of the file is ‘var/log/product_debug.log’.

It is also possible to use mageDebugBacktrace() function for the Magento debugging. By using it, you will be able to get files call stack. It is often used to see the order.

How to view the log

There is no need to refresh the screen to view the log. You just have to use command line tools. There is unix command line utility ‘tail’. From the Magento log folder,  use -f via ‘tail’ as a parameter to open your log file:

Now, you know how to see the changes in a real time.

Varien_Object is a parent class to the most of the Magento models and it has a useful debug method, required to get readable model’s data. Imagine the situation, when you need to get the current product’s data. You have to debug a product’s model:

 The difference between this solution and Zend_Debug::dump($product->getData()) is simple. In a case with getData() call, you get information about all data items of the object, and a list of the object’s properties, if some item is an object. In the same case with a debug() method, you get just object’s data.

Use the following construction to get class methods:

 As a result, you will be able to see a limited list of object’s methods. But at the same time, you won’t be able to see methods arguments.

For the blank pages of a live store. open index.php in a Magento root directory and go to the line with:

 Use your IP to surround it:

This will help you to find the error as fast as possible.  Keep in mind, that Mage::setIsDeveloperMode(true) at this point can cause some additional troubles.

Template Path Hints

For the situation, when it is necessary to detect a *.phtml file from a remote server, you can use template hints:

  1. Go to Admin->System->Configuration.
  2. In the “Current Configuration Scope” choose the necessary site.
  3. Find the ‘Developer’ tab.
  4. Go to ‘Debug’ section and enable “Template Path Hints” and “Add Block Names to Hints”.
  5. Don’t save anything at this step.
  6. If you are not going to “improve” the design of site, restrict the option by the IP: find the “Developer Client Restrictions” section and put your IP there.
  7. Save the changes.
  8. If everything is Ok, you’ll see something like this example:
Template Path Hints

The example

Before starting debugging, you should always check Admin->System->Configuration->Advanced to ensure that the output isn’t disabled.

How To Log Database Queries

There is a feature in the Varien library designed to log database queries to a file automagically. It provides a detailed information about Magento behind-the-scenes functionality and helps to debug different problems, such as slow-running queries and model-based performance issues.

To enable the feature, you have to open the lib/Varien/Db/Adapter/Pdo/Mysql.php file in your text editor. As a result, you’ll see the following class variables down around line 86:

Where:

  • protected $_debug = false;” is the switch used to turn on or off SQL debugging. To enable the process,  use “true”
  • protected $_logQueryTime = 0.05;” sets the minimum time to determine which queries should be logged. You can use this variable to find slow queries that impact the performance of store. Use “1.0” second instead of “0.05” to find really slow queries.
  • protected $_logAllQueries = false;” is used to dismiss the aforementioned variable and log everything. To enable this option, set it to “true”. As a result, you will get a general sense of the database operations.
  • protected $_logCallStack = false;” is used for debugging third-party modules. The option logs a backtrace of methods responsible for calling the query.
  • protected $_debugFile = ‘var/debug/sql.txt’;” sets the location of the debug file.

Before enabling this debugging feature, limit access your site. In order to achieve this, you have to edit the appropriate section of .htaccess file.

And don’t forget to turn off debugging after you troubleshooting is finished.

Varien Object Debugging

Unfortunately, PHP step debuggers aren’t as common as they should be. At the same time, Magento’s abstractions produce the situation where an object revisits the same places over and over again. There’s also the common problem of debugging. To make your life easier, you should be able to debug with Varien Object. In this article, you will learn how to do this.

The other advices

Enable PHP Errors

To enable PHP errors, you can use both a more permanent solution and merely something more temporary.

Permanent solution

For Apache/mod_php

  • Go to document root’s .htaccess file.

  • Drop this at the top:

For Nginx/FastCGI

  • Do the same In Nginx virtualhost configuration.

  • You can use location .php { directive, or fastcgi_params file (if you have a specified one).

  • Drop this at the top:

Temporary/Universal solution

The solution works for every platform.

  • Go to document root.

  • Edit the Magento bootstrap index.php

  • Uncomment the following:

Enable Developer Mode

For errors strings like 2184267227721,there are also a few options.

Permanent solution

For Apache/mod_php

  • Go to document root .htaccess file.

  • Drop the following at the top:

For Nginx/fastcgi

  • Do the same In Nginx virtualhost configuration.

  • You can use location .php { directive, or fastcgi_params file (if you have a specified one).

  • Drop this:

Temporary/Universal solution

  • Go to your document root.

  • Edit the Magento bootstrap index.php

  • make the if statement always true:

  •  or make the if statement enabled for your specific IP:

Check your permissions

Incorrect permissions always cause a lot of problems. Often, it is very difficult to find them.

The example. In the situation, when PHP can not write to the ./media directory and the JS combine is enabled, the system is unable to work with the media correctly and to produce the combined file and associated unique URI for it. A full server path to the media file is in source code of browser (/home/path/public_html/media/xxx).

The practice is secure only for the dedicated hosting. The security issues are common for shared hosting in case where the Apache process isn’t chroot’ed per user.

In the aforementioned example, the Apache user is apache, the SSH/FTP user is sonassi, and the group is apache

FTP/SSH user and the Apache group

FTP/SSH user should be a part of the Apache group. In the aforementioned example, it is apache, but it can also be www-data

Add as many users as you have in FTP/SSH.

Original permissions

Make sure that all the permissions are correct and reset the original permissions.

Permanent changes

ACLs and Sticky Bits

In Linux, ACLs allow to define specific rules. For instance, what permissions should be inherited upon creation by files. In their turn, sticky bits take care of group inheritance. At the same time, they don’t help with permissions, so we have to use ACLs.

Ensure, that your Kernel is compiled with ACL support, and enable the support on the active partition.

The partition can be /home, /var or something else.

Set the ACL rules and group the sticky bits:

If your Kernel doesn’t have ACLs support, you can use umask to set the permissions for the default file. In index.php file change the umask line to umask(022);

Set umask 022 in either .bashrc or .bash_profile in the BASH environment for SSH. The principle for the FTP server is the same. Read the dedicated documentation for the additional information.

Revert theme to default

A new theme or a package can be both responsible for the issue. To solve the problem, you can go back to a vanilla theme.

To rename the offending directories Via SSH, use:

Via FTP client, traverse your package and rename it to something like myCrashedTheme.tmp

If this resolves the problem, you should find the problematic part of the template. Enable directories gradually as you traverse down the file tree. and you will find the offending file at a certain point.

  1. Rename the layout directory to .tmp
  2. template directory  – to .tmp

Then something fixes the issue, rename all files from the layout directory into .tmp. ls | xargs -I {} mv {} {}.tmp or rename ‘s/^/.tmp/’ * for SSH users. After this procedure, you have to enable each file 1 by 1 gradually until the problem is resolved.

If the issue is not resolved, base/default or enterprise/default directories can be contaminated. To fix this, you can use a known clean version. Download Magento clean build and replace the directories. Via SSH:

 Diff the both directories to verify changes:

Disable local modules

In Magento, PHP include path uses the following order to load classes: Local > Community > Core

  • Files from Local should be only loaded.
  • The same about files from Community.
  • If files can’t be found anywhere else, you should load them from the Core.

Don’t disable modules from the admin panel, do it at a file level. Edit the ./app/etc/modules/MyModule.xml file and set <active>false</active>.Keep in mind, that, these actions don’t prevent a class from loading. If any other class extends a given class in a module, it will be loaded in any case. In this situation, the best way to disable any extension is to rename the directory.

First of all, try to rename the directory via FTP. You can also use the following SSH command:

Then you should try to disable community:

If the issue is resolved, you should find out, what module causes the problem. Apply the same actions as with the example with the packages: enable modules one-by-one until the error re-occurs

  1. In the directory, rename the modules to .tmp. ls | xargs -I {} mv {} {}.tmp or rename ‘s/^/.tmp/’ * for SSH users.
  2. Remove .tmp from the file name of every module gradually to enable each module one-by-one.

If the issue is not resolved, there is a possibility, that the core is contaminated. The main Magento PHP core consists of ./app/code/core and ./lib. Rename the directories and copy them in a clean variant. Do this for a clean Magento version:

If this doesn’t help, you should also replace lib directory

It will turn your Magento store into its vanilla version with a modified database.

Callstack Debugging

Callstack is a useful debugging tool for Magento. Call it from anywhere and get the function call stack. As a result, you will be able to see where the current function was called from.
Get Callstack from Github