Magento Compiler Mode

Like this article? Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

This article refers to a beta-ish feature of Magento Community Edition 1.4.2, and therefore the specifics may quickly fall out of date. Proceed will all due caution

There’s a performance improvement feature of Magento that exists in this weird pseudo-beta state. There’s no exposed interface for it, but it does ship with the core codebase and is in wide enough use that’s it’s worth mentioning. I’m talking about the Magento “Compiler”.

(It’s been pointed out to me on twitter that the compiler interface is located at
System -> Tools -> Compiler. We regret the error, and offer as defense HEY LOOK OVER THERE! That was close. Ahem. [awkward silence]. This article still has some useful tips for dealing with the compiler via the command line )

In computer science the term compiler usually refers to transforming code from one language (like C) into another language (like binary machine code). The Magento compiler transforms PHP code into – more PHP code!

Here’s the deal. Magento’s source is spread out over a large number of modules.

app/code/core/Mage/Core/Model/Abstract.php
app/code/local/Foo/Module/controller/FooController.php
etc ...

It turns out that having PHP search for a large number of include files over a large number of different directories can create a performance bottleneck under certain types of load. To combat this, the Magento core team created the Magento Compiler extension, and started shipping Magento with this functionality around version 1.4 CE.

What the compiler does is makes a copy of every class in a Magento system and places them in a single folder. The class’s full name is used for the filename to ensure uniqueness

include/src/Mage_Core_Model_Abstract.php
include/src/Foo_Module_FooController.php
etc...

This is done once. Then, when Magento is configured to use the compiler classes, its autoload will look in the compiler folder instead of running its normal autoload routine. This spares PHP the overhead of transversing the file system for all the different include paths.

Using the Compiler

Magento ships with a command line script for interacting with the compiler. It gets the job done, but can be a little fussy. Make sure you follow these directions precisely until you know what’s going on

Open a command prompt to the root of your store, and type

$ cd shell
$ php -f compiler.php help

This assumes you have PHP available on the command line. If not, see your system administrator (or, you know, Google). You should see output something like the following

state         Show Compilation State
compile       Run Compilation Process
clear         Disable Compiler include path and Remove compiled files
enable        Enable Compiler include path
disable       Disable Compiler include path
help          This help

This is a list of commands to use with the compiler. Some of these commands assume you’re running from the shell folder, which is why we had you cd into shell first. Let’s try compiling our system. You’ll want to experiment on a non-production system, as errors during compilation can white screen your store. Type the following

$ php compiler.php compile
Compilation successfully finished
$

This may take a few minutes, as Magento is traversing your system and pulling out every possible class. If you take a look at the includes/src directory, you’ll see all your classes (over 5500 of them!)

$ ls ../includes/src

You can also get some stats on your compilation by typing

$ php compiler.php state
Compiler Status:          Enabled
Compilation State:        Compiled
Collected Files Count:    5602
Compiled Scopes Count:    4

You probably noticed Compiler Status: Enabled. This is one of the fussy things we mentioned. After compiling your classes, Magento immediately puts itself into “read from the compiled code” mode. You can turn this off by doing

$ php compiler.php disable
Compiler include path disabled
$ php compiler.php state
Compiler Status:          Disabled
Compilation State:        Compiled
Collected Files Count:    5602
Compiled Scopes Count:    4

Your compiled classes will still be there, but now Magento is loading classes from its normal code pools. If you wanted to remove the compiled classes, running

$ php compiler.php clear
Compilation successfully cleared
$ php compiler.php state
Compiler Status:          Disabled
Compilation State:        Not Compiled
Collected Files Count:    0
Compiled Scopes Count:    0

will do the trick. Clearing the files will also automatically disable compiler mode.

Manually Managing Compiler Mode

There’s a file at

includes/config.php

that contains two PHP lines

@syntaxhighlight@php
#define('COMPILER_INCLUDE_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR.'src');
#define('COMPILER_COLLECT_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR.'stat');

The COMPILER_INCLUDE_PATH is the constant that controls whether or not PHP is operating in compiler mode. The compiler.php command line script will scan this file for this line, and comment it or uncomment it based on the actions its performing. Ideally, you should never edit this file by hand. However, if you must, then make sure you continue to use the # to comment/uncomment the constant definition, or else compiler.php may break.

Other Gotchas

Enable compiler mode, and then return to the root folder of your Magento site, and run the state command

$ pwd
/path/to/magento1point4.2/shell
$ php compiler.php enable
$ cd ..
$ php shell/compiler.php state
Compiler Status:          Disabled
Compilation State:        Compiled
Collected Files Count:    5602
Compiled Scopes Count:    4

This is one of those fussy things we were talking about. Running the script from a folder other than shell will always report compiler mode as being Disabled.

The other, larger, gotcha to watch out for is installing new modules while compiler mode in on. You new classes won’t be included in the compiled include/src folder, but their configurations (and events) will be included in the system. This usually means Magento attempts to instantiate one of your classes, but can’t find it in the compiled classes, and will white screen die. You can fix this by turning compiler mode off, recompiling, and then turning it back on.

Larger Vision

So that’s the Magento compiler. While it’s separate from things like Opt-Code PHP compiling/caching, it can bring an immediate performance boost to a site that’s running slow due to large number of files being included on any Magento request. It’s certainly a tool you’ll want in your Magento arsenal.

It’s also points to a certain sort of culture among the Magento core team that’s worth getting familiar with. Despite their choice of PHP as a platform, it’s clear Magento’s engineers aren’t PHP developers. They’re software engineers who happen to be using PHP. Most PHP developers immediately shun the idea of a system as abstract as Magento, in part because of performance considerations.

To someone who’s a software engineer first, you don’t worry about performance. You build yourself an abstract system, and then using your knowledge of software engineering (code compilation/transformation, caching, etc.) you solve the performance problems as they come up.

Neither approach is right or wrong; like anything in this profession it’s a matter of tradeoffs. However, as Magento developers, knowing what tradeoffs the core team has made can help you solve you own problems faster. Knowing why someone did something is always more useful than getting angry at someone who’s doing something different than you would.

Originally published February 1, 2011
blog comments powered by Disqus