Case against templates

Quick Links

Image Upload and Resize with PHP (http://www.raditha.com/megaupload/image.php)

Applets and Proxy Detection (http://www.raditha.com/java/proxy.php)

PHP readfile vs include

Many pundits have written eloquently about templating engines for PHP, the truth is that many templating systems go against the grain of PHP. Let's illustrate this point by studing a few lines of code from a blog/CMS that uses such a templating system.

$query = "SELECT * FROM  posts WHERE topic_id = '$topic_id'
          ORDER BY post_date DESC";
$res = mysql_query($query);
if (!$res || !mysql_num_rows($res))
    return (false);
     
$posts = array();

while ($row = mysql_fetch_array($res)) {
     $row['post_permalink'] = 'post.php/'.$row['post_id'];
     $row['post_trackback_ping_url'] = 'trackback.php/'.$row['post_id'];
     ...
     ...
     $posts[] = $row;
  }

What this code does is fairly obvious, it retrieves a list of posts from the database and loads them into an array. It is equally obvious that doing so will result in the consumption of a lot of memory, particularly if your result set has hundreds or thousands of records. What exactly happens to this array? see the code sample below:

for ($c = 0; $c < count($posts); $c++) {
   $tpl->assign('POST', $posts[$c]);
   $tpl->parse('main.posts_list.post');
   ...
   ...
}  

A few lines of code has been removed for clarity. $tpl is obviously an instance of the template class, and we can see that that code loops through the array and assigns each element of the array to an element of the template. After this assignment the template element is parsed.

We shall not go into the code of the parse() function, suffice to say it is 31 lines long and packed with memory and CPU hungry regular expressions functions. Oh, and btw there is yet another loop inside parse()

Now we have two copies of the data that was originally in the database in memory. The first in the form of a simple array, the second in the form of a several strings; which is the result of the $tpl->parse() method calls. That does not take into consideration the memory required to hold the template itself, and the memory needed to load the templating class.

We still have to print out this string before any output can be seen. Guess what printing the parsed template involves yet another loop. All in all we are looping four times with each query.

Now consider the other approach, simply echoing out each row of the resultset as it's read in:

$query = "SELECT * FROM  posts WHERE topic_id = '$topic_id' ORDER BY post_date DESC";
$res = mysql_query($query);

if (!$res || !mysql_num_rows($res))
    return (false);
     
$posts = array();

echo '<table>';
while ($row = mysql_fetch_array($res)) {
     printf('<tr><td><a href="%s">%s</a></td>', 'post.php/'.$row['post_id'], 'post.php/'.$row['post_id']);
     printf('<td><a href="%s">%s</a></td></tr>', 'trackback.php/'.$row['post_id'],'trackback.php/'.$row['post_id']);
     ...
     ...
  }

We loop only once, we keep nothing in memory, the output is produced instantly and we have managed to do it in a just two lines of code. What can be simpler?

Now suppose for a moment that a new member is joining your team and he is still wet behind the year. If you had used the templating approach he would have to learn about mysql queries, array manipulation, regular expressions and the templating engine itself before he is completely familiar with the system.

Now suppose you had written the project the way it's supposed to be written - without templates, the newcomers only needs to know the mysql functions and printf(). So much for the myth that 'web apps with template systems are easier to maintain'