THE WEBBOX ARCHITECTURE (a PHP implementation of ColdFusion's "Fusebox"
architecture).
Almost any interactive website breaks down into logical divisions. For
example, there is sometimes a "People" section of the site where you can
create an "account" for yourself, log in to your account, edit your account,
etc; on e-commerce sites there's always an "Order" section where you create
order, check an order's status, cancel an order, update an order, etc. In
the webbox architecture each of these functional areas is made into a PHP
object with a thin wrapper around it to allow each of the object's functions
to be called and receive arguments via URL, form action or via PHP script.
The object plus its thin wrapper layer and other supporting files, I call a
"webbox". The functions that can be called on the webbox, I call
"boxactions". I use the term "webbox" for the wrapped object because this
entity isn't really a pure PHP object anymore (it can't be subclassed) and
because of the one feature that distinguishes its "boxactions" from regular
PHP class functions -- that they can be called directly from URLs or form
actions. The implementation of this feature is the whole purpose of the webbox
architecture. Without it, "webboxes" are nothing more than regular PHP
objects, and I should not use any new terminology.
The boxactions of each webbox should be able to do anything PHP can do -- write
HTML out to the browser, perform queries on relational databases, send e-mails,
look in LDAP directories, launch programs on the host system, create GIF
images, encrypt data, create PDF files, parse XML documents, open network
sockets, etc.
Each webbox is composed of several files and is stored in a single
directory with an index.php3 file. To call a boxaction, the desired
webbox's index.php3 URL is called and also passed the name of the boxaction to
call along with any arguments to it. A typical URL style call would
look like:
<a href="/people/index.php3?boxaction=viewcustomer&custid=12345">View Customer</a>
A typical form-based call to the same boxaction can be written:
<form action="/people/index.php3" method=post>
<index type=hidden name="boxaction" value="viewcustomer">
Enter the customer's ID number: <input type=text name="custid">
<input type=submit value="View Customer Record">
</form>
A given webbox's boxactions are implemented in a single class called a
"gateway". The index.php3 script instantiates the "gateway"
class for its box. A long switch statement on the $boxaction parameter chooses
the boxaction to call. Continuing our "add a customer" example, the relevant
snippet of code from the index.php3 file might look like this:
<?php
$homedir = "/www/htdocs/people/";
include $homedir . "gateway.php3";
$g = new Gateway_People($homedir);
switch ($boxaction) {
case "viewcustomer":
$g->viewCustomer($custid);
break;
case "checkauthentication":
$g->checkAuthentication($username, $password);
break;
//
// Other boxactions
//
default:
$g->showDefaultPage();
break;
}
?>
As is clear from this example, the gateway class is stored in a file named
gateway.php3, and the class is named "Gateway_<name>", where <name> is the "name" you've given to the box (in our example the name is "People"). The gateway class is stored in a .php3 file to avoid exposing secrets like
passwords or other sensitive information you don't want the public to see. It
should only contain the class definition, no active script or HTML. Having
the gateway class is necessary for calls to a webbox from script outside its
directory [For you fusebox aficionados out there, the gateway is necessary
because there is no <CFMODULE> tag in PHP which allows you to pass arbitrary
arguments.]
The boxactions implement their functionality by calling other
objects, INCLUDing .php3 file, etc. The gateway class instantiation passes
the box's directory to the constructor because INCLUDE statements in the
gatway class need the full path to the .php3 file. This is
necessary for boxaction calls that originate in directories outside the box's
directory.
Some gateway functions are fully private to the gateway class, being called
only internally. These should be prefixed with an underscore or some other
identifying prefix or suffix to denote that they are "private" functions.
Boxactions or private functions which produce no output should be prefixed with
some abbreviation of the action the function does, like "qry_".
Obviously, the gateway class is the repository for all the implementation of
the boxactions. Thus the gateway class can have MANY lines. To
reduce the size of the gateway class file, remember to delegate tasks to other
classes, static HTML files, and .php3 files.
CALLING BOXACTIONS FROM PHP SCRIPT
To call a boxaction from PHP script, simply instatiate the appropriate gateway
class and call the function on it. Here's an example calling our "View
Customer" boxaction from PHP script:
<?php
include $web_root_directory . "people/gateway.php3";
$people_g = new Gateway_People($web_root_directory . "people/");
$people_g->viewCustomer($custid);
?>
The real beauty of this is the reusability of the code. Because we are wrapping
basic functions in classes, they can be included for use throughout a site.
It's also a win for any future programmers that have to look at the code. A quick glance
at the index file will show you the case statement and the corresponding classes. That's
quite a bit cleaner than searching through dozens of separate php files and includes to
get an idea of what's happening.
I hope this helps you get started. For more information, you can visit
www.fusebox.org..
--Bill