Abstract:

There were a couple of discussions on the PHP3 mailing list about whether PHP is a scripting language or just for embedding in HTML only. From the web application developer's point of view, I would use PHP as an alternative to Perl/Java. In this article, I will show you how to write PHP classes and how to use class.layout (download) to program your web applications.

Main:

PHP3 has the power for serious web applications programming. If you want to create dynamic web applications, embedding data in HTML tags is not enough. Please unleash the power of PHP. One big thing missing from the PHP community is that the lack of useful classes or libraries which makes Perl so successful. Class.layout is an attempt to create useful libraries for PHP progammers.
The key benefits of PHP Layout class are:
  1. Pure programming without dealing with HTML tags. You don't have to count <TABLE>,<TR> etc. HTML tags anymore.
  2. Achieve the most flexbility in web page creation.
  3. Fast development.
Instead of waiting for templates from designers, you have the full power to quickly create COMPLEX pages from class.layout. PHP Layout Class uses object programming, but also provides "helper functions" for easy usage and hides the implementation detail from users.
The raw object-programming syntax to create a table in class.layout is:

<?php
    $atable 
= new Table(array("width"=>"500"));
    
$window->insert($atable);
?>
But class.layout also provides "helper functions" - 'insert' and 'table' which makes it more instinctive for non-object-programming users and requires less typing.

<?php
    insert
($windowtable(array("width"=>"500")));
?>
An entire complex web site or application can be written with a bunch of 'insert's. The design of class.layout comes from the fact that most of the HTML tags are in pairs and like a container with lots of attributes. Look here:
	<A HREF="/index.html">Homepage</A>
<A> and </A> is a pair and 'HREF="/index.html"' are the attributes of the tag <A>. A simple Anchor object would be:

<?php
class Anchor {
    var 
$source "";
    var 
$attributes = array();
    
    function 
Anchor ($s,$a) {
        
$this->source $s;
        
$this->attributes $a;
    }

    function 
printit() {
        echo 
"<A ";
        while(list(
$key,$val) = each($this->attributes)) {
            echo 
"$key =\"$val\" ";
        }
        echo 
">"
        echo 
$this->source ; echo "</A>";
    }
}
?>
Now you can create the:
	<A HREF="/index.html">Homepage</A>

with the following code lines:

<?php
    $a 
= new Anchor("/index.html",array("href" => "Homepage"));
    
$a->printit;
?>
People will ask questions like this: It doesn't seem to simplify the job, perhaps requiring even more typing? That is true for a 10 line web page but definitly NOT for a 500 line web page. The benefits are not limited to this only. Any complex web site uses tables, forms, frames extensively and most of them are nested in each other. Creating these kinds of pages is really a challenge if you are not using class.layout.
Enough talking about the design. Let's start with a simple web page.

<?php
    newhtml
($w);
    
insert($w,wheader("A Test Page"));
    
insert($w,$t table(array("cols"=>"2","width"=>"650")));
    
insert($t,$c cell(array("colspan"=>"2")));
    
insert($c,text("TEST ONLY"));
    
printhtml($w);
?>
The function 'newhtml' starts a container with a pair of HTML tags <HTML> and </HTML>. It is the parent of all other containers thereafter. function 'wheader' (avoid conflicts with built-in function 'header') creates a pair of <HEAD>,</HEAD> and contains '<TITLE>A Test Page</TITLE>'. A table is created and is inserted into the window container with another 'insert'. Once all the construction is finished, 'printhtml' prints the results right away.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
    <TITLE>A Test Page</TITLE>
</HEAD>
<BODY>
     <TABLE WIDTH="650">
     <TR>
    <TD COLSPAN="2"><FONT>TEST ONLY</FONT></TD>
     </TR>
     </TABLE>
</BODY>
</HTML>
We can add more fancy things now with the function 'setdefault' at the beginning of the script.

<?php
    setdefault
("window",array("bgcolor"=>"white"));
    
setdefault("table",array("cellpadding"=>"0"));
    
setdefault("text",array("size"=>"2"));
?>
These functions set the default attributes for the 'window', 'table' and 'text' objects. The result would be:
<BODY BGCOLOR="white">
<P>
<TABLE WIDTH="650" CELLPADDING="0">
<P>
<FONT SIZE="2">
Is this simple enough? Ok. Many of you may ask: How about much more complex situations? Let's go over the source of http://www.vhconsultants.com/index.htm
line 1: <?php
line 2: include("/apache/htdocs/template1.inc");
template1.inc is used for creating the banner part, menu, and left side column on the page. I keep it in one file and include it in most of the pages at the site. I will go over the file later.
line 3: insert($c2,generic("hr",array("noshade"=>"undef","size"=>"1")));
There is no <HR> constructor in the class.layout(to make it small) But it does provide a generic way to construct HTML tags. function 'generic' takes two arguments, arg 1 is the tag name, arg 2 is the attributes array. '$c2' is a cell from 'template1.inc', The result of line 3 would be:
<HR NOSHADE SIZE="1">
Since we are going to use it a lot in the page. I would define a local function for it...

<?php
function aruler() {
    eval(
"insert(\$c2,generic(\"hr\",array(\"noshade\"=>\"undef\",\"size\"=>\"1\))); " );
}
?>
So next time, I can use aruler() to create the <HR> tag.
line 4: insert($c2,text("UNDER CONSTRUCTION !!",array("color"=>"red")));
line 5: aruler();
line 6: insert($c2,text("<B>Launch www.vhconsultants.com (05/24/99)</B>"));
Sometimes, it is much easier to insert tags directly like '<B>' used here (line 6) to avoid another line/layer of 'insert'.
line 7: insert($c2,text("<P>We are a group of ...."));
line 8: insert($c2,$f2 = container("font",array("face" =>
		"verdana,arial,helvetica","size" => "2")));
line 9: insert($f2,alist("UL",array("Large web sites architect/design",
					 "Web application programming")));
Here we introduce another generic constructor 'container' which differs from 'generic' in a way of of providing a pair of HTML tags. Here we use it to control the font of the list. the result of line 8 and line 9 would be:
	<FONT FACE="verdana,arial,helvetica",SIZE="2">
		<UL>
		<LI>Large web sites architect/design
		<LI>Web application programming
		</UL>
	</FONT>
Keep going.
line 10: aruler();
line 11: insert($c2,text("<B>Annouce the PHP Layout Class</B>"));
line 12: aruler();
line 13: include("/apache/htdocs/template2.inc");
Line 13 here is the last part of the page, which is also same across the whole site. From the samples above, you can see how easy it is to create a uniform look and feel across the whole site.
Now we can dissect template1.inc in detail for getting further with class.layout.
line 1: setdefault("window",array("bgcolor"=>"white"));
line 2: setdefault("table",array("cellpadding"=>"0"));
line 3: setdefault("image",array("border"=>"0"));
line 4: $width = 650; $fircl = 150; $seccl = $width - $fircl;
line 5: newhtml(&$w);
line 6: insert($w,$h = wheader("VH Consultants"));
line 7: insert($w,$d = container("div",array("align"=>"left")));
line 8: insert($d,$t = table(array("width" => $width )));
line 9: insert($t,$c = cell());
line10: insert($c,image("/header.gif",array("width"=>$width,
			"height"=>"60")));
line11: insert($t,$c = cell(array("align"=>"right")));
line12: insert($c,anchor("/index.htm",
		image("/title/2/16/home.gif",array())));
line13: insert($d,$t = table(array("width" => $width )));
line14: insert($t,$c = cell(array("align"=>"center")));
line15: insert($c,$t1= table(array("width"=>"100%","cols"=>"2")));
line16: insert($t1,$c1 = cell(array("width"=>$fircl,
		"bgcolor"=>"#B1A0CA","valign"=>"top")));
line17: insert($c1,$t2 = table(array("width"=>"100%","cellspacing"=>"2",
		"cellpadding" =>"3")));
line18: insert($t2,$c2 = cell(array("align"=>"left","bgcolor"=>"#B1A0CA")));
line19: insert($c2,image("/title/2/20/projects.gif",array()));
line20: insert($t2,$c2 = cell(array("align"=>"left","bgcolor"=>"#FFFFFF")));
line21: insert($c2,$f2 = container("font",array("face" =>
		"verdana,arial,helvetica","size" => "2")));
line22: insert($f2,anchor("/layout.htm","PHP Layout class<BR>"));
line23: insert($f2,anchor("/graph.htm","PHP Graph class<BR>"));
line24: insert($f2,anchor("/forum.htm","PHP Forum class<BR>"));
line25: insert($f2,anchor("/pdf.htm","PHP PDF class<BR>"));

line26: insert($t1,$c1= cell(array("width"=>$seccl,"valign"=>"top")));
line27: insert($c1,$t2= table(array("width"=>"100%","cellpadding"=>"15")));
line28: insert($t2,$c2= cell(array("align"=>"left")));
There is nothing fanncy about template1.inc. It creates the web page with several layers of tables. The whole web page is contructed in tables for strict alignment of components and to maintain consistant rendering across different browsers.
The design goal of class.layout is flexibility and speed. The whole class is about 900 lines of code and provides the following functions:
	function insert($p,$c)
	function defsetting($a)
	function newhtml(&$w,$a = "")
	function printhtml($w)
	function table($a = "")
	function cell($a = "")
	function image($s,$a,$ni = "")
	function anchor($h,$s,$a = "")
	function block($t,$ni = "")
	function text($t,$a = "")
	function form($a = "")
	function alist($t,$c,$a = "")
	function comment($m)
	function generic($t,$a = "")
	function container($t,$a = "")
	function script($c,$a = "")
	function wheader($t)
	function heading($l,$c,$a = "" )
	function button($a)
	function checkbox($a,$t,$c = "")
	function inputfile($a)
	function hidden($a)
	function imagebutton($s,$a)
	function password($a)
	function radio($a,$t,$c = "")
	function freset($a)
	function submit($a)
	function input_text($a)
	function select($o,$a,$s = "")
	function textarea($a,$m = "")
	function imagemap($a)
	function area($a)
	function layer($a)
	function nolayer($m)
	function frameset($a)
	function frame($a)
	function noframe($m)
	function style($m,$a)
	function insert($c)
You may start to convert your existing HTML page into PHP script using this class.graph. Believe me, it is really fun when you don't have to worry about echoing and printing everywhere. Here is the style I use for web applications programming.
	<?php

		include("reusable code");

		define local functions;

		call application related functions (getting data from
		database etc.)

		start html with newhtml(&$w);

		construct page  ....

		print page with printhtml($w);

	?>