Home arrow PHP arrow Page 3 - Using a Template Processor Class in PHP 5

Parsing template files: defining the input tags for the “TemplateProcessor” class - PHP

Welcome to part two of the series “Separating logic from presentation.” Comprised of three articles, this series walks you through the development of an extensible template processor in PHP 5, which you might find quite useful for separating the logic of your PHP applications from their visual presentation.

TABLE OF CONTENTS:
  1. Using a Template Processor Class in PHP 5
  2. Getting started using the “TemplateProcessor” class: a quick look at its definition
  3. Parsing template files: defining the input tags for the “TemplateProcessor” class
  4. Going one step further: seeing the “TemplateProcessor” class in action
By: Alejandro Gervasio
Rating: starstarstarstarstar / 4
May 09, 2006

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Right, I think the best way to demonstrate the functionality of my “TemplateProcessor” class is simply by feeding it a considerable variety of data, which will be eventually parsed and displayed within the corresponding template file, after performing the replacement of placeholders. Considering this, I’ll first define two dynamic files, “header.php” and “footer.php” respectively, which will compose the header and footer sections of a sample web page. Take a look at these two basic PHP files:

<?php
echo '<h1>This is the header section and was generated at the
following time '.date('H:i.s').'</h1>';
?>

<?php
echo '<h1>This is the footer section and was generated at the
following time '.date('H:i.s').'</h1>';
?>

Now, after listing the above PHP files, I’ll include a simple MySQL result set as part of the input of the “TemplateProcessor” class. To do this, I’ll use two additional MySQL wrapping classes, which are listed below:

// define 'MySQL' class
class MySQL{
    private $host;
    private $user;
    private $password;
    private $database;
    private $connId;
    // constructor
    function __construct($options=array()){
        if(!is_array($options)){
            throw new Exception('Connection options must be an
array');
        }
        foreach($options as $option=>$value){
            if(empty($option)){
                throw new Exception('Connection parameter cannot
be empty');
            }
            $this->{$option}=$value;
        }
        $this->connectDb();
    }
    // private 'connectDb()' method
    private function connectDb(){
        if(!$this->connId=mysql_connect($this->host,$this-
>user,$this->password)){
            throw new Exception('Error connecting to MySQL');
        }
        if(!mysql_select_db($this->database,$this->connId)){
            throw new Exception('Error selecting database');
        }
    }
    // public 'query()' method
    public function query($sql){
        if(!$result=mysql_query($sql)){
            throw new Exception('Error running query '.$sql.'
'.mysql_error());
        }
        return new Result($this,$result);
    }
}
class Result{
    private $mysql;
    private $result;
    // constructor
    public function __construct($mysql,$result){
        $this->mysql=$mysql;
        $this->result=$result;
    }
    // public 'fetch()' method
    public function fetch(){
        return mysql_fetch_array($this->result,MYSQL_ASSOC);
    }
    // public 'count()' method
    public function count(){
        if(!$rows=mysql_num_rows($this->result)){
            throw new Exception('Error counting rows');
        }
        return $rows;
    }
    // public 'get_insertId()' method
    public function getInsertId(){
        if(!$insId=mysql_insert_id($this->mysql->connId)){
            throw new Exception('Error getting insert ID');
        }
        return $insId;
    }
    // public 'seek()' method
    public function seek($row){
        if(!int($row)&&$row<0){
            throw new Exception('Invalid row parameter');
        }
        if(!$row=mysql_data_seek($this->mysql->connId,$row)){
            throw new Exception('Error seeking row');
        }
        return $row;
    }
    // public 'getAffectedRows()' method
    public function getAffectedRows(){
        if(!$rows=mysql_affected_rows($this->mysql->connId)){
            throw new Exception('Error counting affected rows');
        }
        return $rows;
    }
    // public 'getQueryResource()' method
    public function getQueryResource(){
        return $this->result;
    }
}

Now that you saw the source code of the two MySQL wrapping classes listed above, which I’ll utilize for fetching a trivial MySQL result set, the next thing to do is define the structure of a sample template file, named “default_template.htm,” that will be parsed in turn by the “TemplateProcessor” class. Please look at the signature of this example template file:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>{title}</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-
8859-1" />
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="header">{header}</div>
<div id="navbar">{navbar{subnavigationbar}{subnavigationbar2}}</div>
<div id="leftcol">{leftcontent}</div>
<div id="content">{maincontent}</div>
<div id="rightcol">{rightcontent}</div>
<div id="footer">{footer}</div>
</body>
</html>

As you can see, the sample template file shown above has some placeholders located in different sections of the web page, which will be removed and replaced with actual data. In this example, both {header} and {footer} placeholders will be replaced with the dynamic output of the “header.php” and “footer.php” files respectively, while {maincontent} will be filled with the MySQL data set that I mentioned before. In addition, the nested {navbar{subnavigationbar1}{subnavigationbar2}} placeholders will be replaced with the contents of the following navigational PHP files:

<?php
// definition for 'subnavbar1.php' file
for($i=1;$i<=5;$i++){
    echo '<a href="file'.$i.'.php?fid='.$i.'">Primary
Link'.$i.'</a> | ';
}
?>

<?php
// definition for 'subnavbar2.php' file
for($i=1;$i<=5;$i++){
    echo '<a href="file'.$i.'.php?fid='.$i.'">Secondary
Link'.$i.'</a> | ';
}
?>

Right, I think that all the above dynamic PHP files, in addition to the MySQL dataset that will be fetched in turn, are enough input data for feeding the input of the “TemplateProcessor” class and seeing how it works. Therefore, go ahead read the next section to see how the corresponding template file is parsed.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
   

PHP ARTICLES

- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...
- PHP: Building Concrete Validators
- Sanitizing Input with PHP
- Executing Shell Commands with PHP
- Handling File Data with PHP
- File Security and Resources with PHP
- ArrayObject PHP Class Examples
- ArrayObject PHP Class: An Introduction
- Getting File System Data with PHP
- PHP Tools for Working with the File and Oper...
- Working with the File and Operating System w...
- PHP Proxy Patterns: Completing a Blog


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 8 - Follow our Sitemap

Dev Shed Tutorial Topics: