The battle of PHP templates
July 13th, 2004There is one debate over within PHP that many people fail to fully understand both sides of. Lots of people who should know better make constant claims regarding the use of one method, and blindly praise the use of the other. Of course, I'm talking about PHP Template Engines.
For those that don't know, a Template Engine (at least in the PHP realm) is a PHP class that uses an advanced form of variable substitution to allow you to define the actual text-based (HTML, RSS, XML, E-Mail message, etc) output of an application seprately from the application itself.
Most people writing any form of large application would agree that this is a good thing. Application code becomes difficult to read when it is littered with HTML tags and other outputs that are meaningless to the actual application code flow. The debate begins when people start to discuss how that Template Engine should operate. Once there is agreement that the layout code should not be intermingled with the application code, there are two schools of thought with two implementations each.
First, there are those that believe that, since PHP itself *is* a template language, PHP should be used as the language in which the template code is written. This is implemented in one of two ways. One can simply include a PHP file that contains template code. This is dirty, in my opinion, as you are either required to have all of the template variables you are going to use in the global namespace or, you must make ugly calls to some sort of template variable class in order to retrieve them. The second method, the way "PHPSavant":http://phpsavant.com/ does it, it to use a PHP class to handle variable scoping, file includes, plugins, and other features. While this certainly uses more overhead than a simple PHP include, the organization and readability of the layout code is drastically improved and the performance hit is well worth it for anything but the simplest of pages.
Secondly, there are those that implement a "language" of their own to express logic within a template. The first implementation of this uses nothing more than variable substituion and block parsing. This means that much of the actual logic for template is contained within the code that calls the template and not the template itself. While this certainly improves the readability of application code over not using a Template Engine at all, real separation means that this layout logic should be separated from the application code entirely. This can be done in make-shift fashion if these "substitution" libraries are used correctly. However, a better alternative is to use a smarter template "language", like "Smarty":http://smarty.php.net/. By allowing the template language itself to be more featureful, the template logic is moved into the template itself. This allows better separation of code at with very little additional overhead as compared to simple variable substituion and block parsing.
There is one other school of thought that involves using a template that handles little more than variable substitution *and* a PHP file to handle the logic together as a single "template". This is more complicated, in my opinion, and more difficult to debug. There are people who use this technique and do it well, however, I will not address it any further do to my ignornace of such methods.
Between these two schools of thought, there is much debate. Most arguments are against Smarty and for systems like PHPSavant. Their strongest argument goes something like "PHP is a template language, so why bother with creating, maintaining, and compiling another language entirely when PHP does everything you need". And, in many ways, this argument is accurate. However, imagine running a large site like "LiveJournal":http://livejournal.com/ in which regular untrusted users are allowed to redefine the templates used to display their pages. Do you really want to give untrusted users access to PHP? And even if you didn't care about their ability to run arbitrary code, remember that the template is being run in the environment that generated the template data to begin with. This means that a even a moderately experienced PHP programmer could easily gain access to the variables and classes that were used to construct the data for the template in the first place. They could access information they don't have permission to, alter configuration files, and have direct access to your database. Is this what you want your untrusted users doing? Probably not. So, in a case like this, PHPSavant, or any PHP-based Template Engine, just doesn't work because it allows the user too much access. Systems like Smarty allow the application programmer to specifically limit what the user can and cannot do within a template.
But what about applications in which the programmer or site owner is the only person who will be editing and maintaining templates? Surely, if this individual decides to do something silly with the extra power they get through using PHP as a template language then that is their own fault. In this simple scenario, it perfectly acceptable to use PHP as the template language. However, imagine now an only slightly more complicated scenario. Imagine an application programmer and a site designer working together. Sure, the site designer can learn a PHP template just as easily (easier?) than they could learn Smarty Templates but, with PHP templates you run the risk that they might do something that would crash the host server, or something that "works" but is difficult to maintain due to some absurd methods being used. With Smarty Templates, they only have a limited set of functionality at their hands. If they need to do something other than what comes out of the box, they have to consult the application programmer.
I hear the nay-sayers screaming now, "but Smarty Templates require regular expression based parsing and that makes the application much slower and more CPU intensive". Not really. When properly setup (the defaults), Smarty reparses only template files that have changed. Once parsed, they are compliled into pure PHP and stored in this fashion. Every subsequent invocation uses this compiled version until a change in the template source is detected. Yes, there is two extra "stat" calls that must take place to determine if a compiled template is available and if the template source has been changed, but, if you're really looking for optimization, even these checks can be disabled. And it's quite possible that the PHP you would author directly is more optimized than the generated PHP created in the Smarty compile process. And there's really no way to measure how much more optimized since the PHP Templates are only as optimized as the PHP coder writing them is capable of.
In conclusion, though I've never used it, PHPSavant appears to be a terrific PHP based Template Engine. If the application you're building will only be designed by you, a designer, or the site owner who installs the application, I'm sure it's the way to go. However, for additional separation, greater assurance of server stability, and greater control over what the designer is allowed to do, a Smarty template will not impact performance much more than PHPSavant will (only two extra "stat" calls and, possibly, less optimal PHP code). And if you intend to let your users edit their own templates, PHPSavant isn't even an option.


















