
One of the most common (and useful) design patterns is the Singleton. The idea is simple: you often only want one instance of a particular resource, and the Singleton pattern makes that possible. For the frameworks, we want to ensure that there is always only one active connection to our PostgreSQL database (for any given client).
PHP Singletons
In an object-oriented PHP application, a singleton is accomplished by making the constructor function a private method while providing a public class method to access the desired resource. The trick is for this public class method to have a static variable that represents the singleton. (Remember, in PHP, a static variable only exists in the function where it is declared, but it keeps its value even after the program execution leaves the function.)
IWDatabase
The root database class in the IWFrameworks is IWDatabase: it is responsible for managing the connection to the back-end database (using the Singleton Design Pattern) and for handling specific types of data requests. Note that each database type (e.g., PostgreSQL or MySQL) has its own adapter, which is responsible for the low-level PHP database calls.
/fw/database/IWDatabase.php
<?php
class IWDatabase
{
protected $database_connection;
private function __construct() { }
public static function databaseConnection($type, $hostname, $database,
$username, $password)
{
static $singleton;
if (! isset($singleton[$database]))
{
$adapter_class = IWDatabase::databaseAdapterClass($type);
$singleton[$database] = new $adapter_class;
$singleton[$database]->initialize($hostname, $database,
$username, $password);
}
return $singleton[$database];
}
public static function databaseAdapterClass($type)
{
switch ($type)
{
case 'pgsql': return 'DBOMPostgreSQLAdapter';
case 'mysql': return 'DBOMMySQLAdapter';
}
}
}
?>
Singleton Subclass
One feature of the IWFrameworks is a series of application helpers: classes and objects that act as gateways to the underlying framework classes and objects. These helpers exist mostly for convenience, implementing methods that nearly any application utilizing the frameworks will need. ApplicationDatabase is an example of such a helper: while IWDatabase is versatile enough, it requires the database information to be passed as arguments each time. ApplicationDatabase works by expecting the presence of four application constants (representing the database host, name, username, and password). How this integration happens in my particular frameworks isn't important: what is important is that this approach demonstrates how you can subclass a Singleton implementation.
Listing: /fw/database/ApplicationDatabase.php
<?php
class ApplicationDatabase extends IWDatabase
{
public static function databaseConnection()
{
return parent::databaseConnection(DB_TYPE, DB_HOST, DB_NAME,
DB_USERNAME, DB_PASSWORD);
}
}
?>
