Saturday, November 12, 2005

 

New PHP app

PHP has changed a lot. Actually that's probably not true, but I have changed a lot. C# opened my eyes to OOP. So when I got an idea that needed a rapid web app with a database tied to it, I turned to PHP first, except now thinking in terms of OO.

There are some easy wins here for PHP developers. Procedural PHP pages typically begin like this:

require_once('dbinfo.php');
require_once('utils.php');
include('header.php');

error_reporting(E_ALL);

$conn = mysql_connect($server, $user, $password, $database);

// blah blah

include('footer.php');
mysql_close ($conn);


Note all the duplication. Even worse is that changing anything here globally becomes more difficult as the number of pages increases. Finally, the namespace is polluted with all kinds of variables and functions that are pulled in by the other files. There are ways around this procedurally, of course, but the OO way is to have each page inherit a base page. The constructor and destructor of the base page handles everything that needs to be handled on every page:

require_once('adodb/adodb.inc.php');
class page_base {
var $dbserver = 'localhost';
var $dbuser = 'user';
var $dbpassword = 'pass';
var $dbdatabase = 'db';
var $db;

function page_base() {
$db =& ADONewConnection('mysql');
$db->debug = true;
$db->PConnect($this->dbserver, $this->dbuser,
$this->dbpassword, $this->dbdatabase);
$this->db = $db;

register_shutdown_function(array(&$this, 'DESTROY'));

error_reporting(E_ALL);
}

function DESTROY() {
$db = $this->db;
$db->Close();
}
}


Subordinate pages inherit like so:

class test extends page_base {
function go() {
[....]
}

}

$obj =& new test;
$obj->go();


Data and methods are encapsulated in the object. Resultantly, object methods always have access to the data they need to work. That keeps things tidy.

This code can be extended with inheritance. The base_page class instantiates an ADODB instance, so every class that inherits page_base will wind up with a database instance whether they need it or not. The solution is to create a page_base_db class that inherits page_base and adds the database connection. Subordinate pages that require the database connection can use page_base_db and reap the benefits of both classes.

One interesting tenet of encapsulation in "true" OO systems is protecting class members. The idea is that an interface (say, the page base class) may have variables and methods that should not be used by another class. True encapsulated systems will actually prevent these members from being accessed from outside their designated scope. Perl (and Perl-derived languages like PHP) do not enforce protection like this. The risk of using "protected" methods or properties is placed on the shoulders of the user. This makes sense since generally the source is available anyway. So, to protect a class member in Perl/PHP: don't write documentation for it and name it differently (perhaps with an underscore) than public members.

Some other nice developments in PHP since I last examined it. Smarty looks fantastic. I love abstraction in my apps and Smarty will help abstract the presentation and business logic even more. Also, I knew I didn't want to do Object-Relational Modeling for this project, but I did want a nice OO interface to the database. ADODB fit the bill nicely. Pear::DB would probably also be very nice but the object model in ADODB is a little closer to what I wanted. If I can pull it off I will probably use xajax to nicen up the UI a bit and speed up the app. Lots of exciting stuff going on.

Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?