By Wee Lep
From preface of the PHP manual, the following states the definition
of PHP scripting: "PHP is an HTML-embedded scripting language.
... The goal of the language is to allow web developers to write
dynamically generated pages quickly."
The phrase "HTML-embedded scripting language" reminds me of my days
in "dot-coms" ("dot-gones" for now). I was involved in the development
of corporate portal sites. My working counterparts were mainly
webpage and graphic designers with little or no programming knowledge.
Since PHP is a "HTML-embedded scripting language", so it becomes
natural to embed my PHP codes in the web pages designed by the
designer folks. Often, I will have to embed PHP codes in HTML pages
to dynamically display the records which I retrieved from database(es).
Take an "Address Book" application for example. We normally store the address book entries : "Name" and "Address" in database. :
+---------------------------------+
| NAME | Address |
+---------------------------------+
| Alvin | Block 112 Bedok Road |
+---------------------------------+
| Robert | 23 Livingstone Road |
+---------------------------------+
:
:
+---------------------------------+
| John | 556 Everton Park Road |
+---------------------------------+
When the time comes to display them in HTML pages, we will normally insert our PHP codes in the HTML page like this :
<table>
<tr>
<td> <b>Name</b></td>
<td> <b>Address</b></td>
</tr>
<?php
..... database extraction codes (omitted) ....
for ($row_nbr=0; $row_nbr < $NUMBER_OF_RECORDS; $row_nbr++)
{
echo "<tr>\n";
echo "<td> " . $recordset_array[$row_nbr][0] . " </b></td>\n";
echo "<td> " . $recordset_array[$row_nbr][1] . " </b></td>\n";
echo "</tr>\n";
}
?>
</table>
In order to place the data into the nicely-designed HTML pages, we
either get the designers to embed our PHP codes in appropriate
locations in their designs and remind them to remember to name
their pages as <filename>.php before they publish or we (programmers)
do it ourselves. I used to adopt the latter option, but in the end,
I got blamed for messing up their HTML-codes :(
And when the time comes to change the layout or design of the HTML page, I would have to "remember" to insert
PHP codes into appropriate positions again. Any slight omission of codes, the whole team (designers) would again look
at me, this time, frowning.
This had set me to think: If I could come up with a way that we (coders and designers) could work together without
either party pointing fingers at the other, efficiency and productivity would be increased. So, I spent time on
developing a way to let us conduct our work independently and yet communicable at the end of the day.
Once again, let us programmers save the day! :) We will make the
designers be happy by letting them only do design. Let them design
their pretty pages for all they want; while we coders, code what
needs to be coded. The idea is as follows:
The Idea
While designers might find it irritating to "copy-and-paste" large
portion of PHP codes in their HTML designs, they will have no
problem putting HTML-comments: "<!-- This is a HTML comment line
-->" in their pages. If these designers could put HTML-comments at
the places where our PHP code would appear then I could provide scripts
to insert PHP codes in them! This idea is similar to template-driven
designs.
In the places where rows of data will be display dynamically (based on database records), we will get them to denote
them with "HTML-comment" tags : "<!--START_ROW-->" and "<!--END_ROW-->".
TEMPLATE.html
<table>
<tr>
<td> <b>Name </b></td>
<td> <b>Address</b></td>
</tr>
<!--START_ROW-->
<tr>
<td> <!--NAME-DATA--> </td>
<td> <!--ADDRESS-DATA--> </td>
</tr>
<!--END_ROW-->
</table>
Coders will need to prepare a script that displays the Address book entries as such:
handler.php
<?php
1: $template_filename = "TEMPLATE.html";
2:
3: ..... database extraction codes (omitted) ....
4:
5: /* =============================================================== */
6: /* ====================== Replacement Rules ====================== */
7: /* =============================================================== */
8:
9: $replacement_rules = array (
10: array ("<!--NAME-DATA-->", "0"),
11: array ("<!--ADDRESS-DATA-->", "1")
12: );
13:
14: /* =============================================================== */
15:
16: $n_fcontents = template_parser ($template_filename, $replacement_rules, $recordset_array);
17: while (list ($line_num, $line) = each ($n_fcontents))
18: {
19: echo "$line";
20: }
?>
What the above script does is to set rules to display our
database-retreived record fields in appropriate columns in the HTML
tables. These rules will be stored in $replacement_rules array
as defined above.
The elements of $replacement_rules array simply let our script know
how to "fill in the blanks".
The variable :
$recordset_array is a 2-dimension array that contains
records which we retrieved from database.
+---------------------------------+
| Alvin | Block 112 Bedok Road |
+---------------------------------+
| Robert | 23 Livingstone Road |
+---------------------------------+
:
:
+---------------------------------+
| John | 556 Everton Park Road |
+---------------------------------+
Line 10 (and line 11) of the code simply is a "rule" that instructs
PHP script to replace occurances of the string <!--NAME-DATA-->
with FIELD 1 (array is "zero-based") of the recordset provided
in $recordset_array array.
All the work will then be performed by the PHP function : template_parser.
The detailed workings of template_parser function is as follows :
function template_parser
function template_parser ($template_filename, $replacement_rules, $recordset_array)
{
$START_FLAG = 0;
$start_anchor=0;
$end_anchor=0;
$res_arr="";
$fcontents = file (TEMPLATES_PATH . $template_filename);
while (list ($line_num, $line) = each ($fcontents))
{
if ($START_FLAG == 0)
{
if (ereg ('<!--START_ROW-->', $line))
{
$START_FLAG = 1;
$start_anchor = $line_num;
}
}
else
{
if (!ereg ('<!--END_ROW-->', $line))
{
$res_arr .= $line;
}
else
{
$START_FLAG = 0;
$end_anchor = $line_num;
}
}
}
/* Build String-Replacement Rules ... */
$tmp_res_arr = "";
$n = count($data_array);
for ($x=0; $x<$n; $x++)
{
$tmp = $res_arr;
for ($y=0; $y<count($replacement_rules); $y++)
{
$a = $replacement_rules[$y][0];
$b = $replacement_rules[$y][1];
if (ereg ("<!", $a))
{
$data_array[$x][$b] = stripslashes ($data_array[$x][$b]);
eval ("\$tmp = str_replace (\"$a\", \$data_array[\$x][$b], \$tmp);");
$tmp = stripslashes($tmp);
}
}
$tmp_res_arr .= $tmp;
}
$res_arr = $tmp_res_arr;
/* Re-constructing the file-contents ... */
$n = count($fcontents);
for ($x=0; $x<$n; $x++)
{
$y = $start_anchor + ($x - $end_anchor) ;
if (($x >= $start_anchor) and ($x < $end_anchor))
{
if ($n_fcontents[$start_anchor] == "")
$n_fcontents[$x] = $res_arr;
}
elseif ($x > $end_anchor)
$n_fcontents[$y] = $fcontents[$x];
else
$n_fcontents[$x] = $fcontents[$x];
}
return ($n_fcontents);
} // end function template_parser
What the above does is to "reproduce" the HTML codes surrounded by both HTML-comment tags :
<!--START_ROW--> and <!--END_ROW--> as many times as the number of rows found in the $recordset_array array, yet with the intelligence to replace data fields (columns of $recordset_array array) in places
defined in the $replacement_rules array without affecting the original HTML formattings.
When all the necessary replacements have been done, the entire HTML page will be "echoed" out by PHP.
Conclusion
By denoting the places where dynamic displays of records will take place using HTML-comments,
PHP codes will be able to insert appropriate data while not "disturbing" the original formatting intended.
I am aware that there will be inefficiencies introduced by asking PHP to "swallow and then regurgitate" HTML codes.
But I believe that these slight inefficiencies will be neutralised by the better management and maintainability of
websites development.
-- Wee Lep