Stubborn objects

January 7, 2009

When I think about persistent data the first idea that always pops into my head is, “singleton.” It’s simple, it’s elegant, and it works. It’s not difficult to implement a singleton in PHP. Set a private constructor, private static member and instantiate the object by calling some public function (usually instance( ) ).  Like so:

<?php
class Singleton {
     private static $singleton;  

     private function __construct( ) { }

     public static function instance( ) 
     {
          if ( ! isset( self::$singleton ) ) {
              $class = __CLASS__;
              self::$singleton = new $class;
          }

          return self::$singleton;
     }
}

$object = Singleton::instance( );
?>

The problem with using a singleton in a server-side language like PHP is scope.  Scope in PHP is based upon requests, which rules out using a singleton pattern if your application is trying to access the persistent data via an AJAX call or something of that sort.  In developing an application that used no PHP on the frontend and relied on all of it’s data by making AJAX calls to a PHP library, I wasn’t able to maintain state on my database with each request.

The goal of this application was to minimize database calls in order to speed up the operation.  We were using an older version of the app at the time which ran on EWD and essentially used a mixture of AJAX and direct database calls for every single operation.  It was slow.  My new design synchronized the database whenever needed and stored it on the PHP backend.  Lets call this class Database.

Database is a class which needed to behave like a singleton.  After all, this library was developed to be portable and therefore all communication was occurring through a series of gateway classes that acted as an interface for AJAX, AMFPHP, or whatever other framework one could dream up.  All of the operations happened during AJAX requests, and therefore a singleton implementation wouldn’t suffice for Database.  The class holds a replica of the existing database so that queries are made to the object rather than the database itself.  This eliminates calls assuming the data we have in the Database object is correct.  There was just no way to use a singleton pattern to keep this object alive and kicking from one request to the next.

Fortunately, PHP provides the tools necessary to handle this. Sessions are a persistent environment where you can store necessary data, and that’s exactly what I did.  Utilizing a tool built into PHP I was able to handle keeping my database object “alive” in the background while the Javascript on the frontend formatted and displayed whatever data I was sending back.  PHP has built-in object serialization (as most modern languages do).  Serializing encodes a custom object into a bytecode string which can then be transformed at any time back to it’s original data type and state. A typical call originating from my gateway would look like this:

public function someFunc( ) { 

    // Fetch the database from the session
    $database = unserialize( $_SESSION['database'] );

    // Query or tweak the database, letting the database
    // object handle any direct DBMS queries if the
    // database was altered. 

    // When finished, store the database back into the
    // session
    $_SESSION['database'] = serialize( $database );
}

So there we have it.  A custom database object that needs to remain persistent across requests stays alive in the session by using built-in serialization.


Follow

Get every new post delivered to your Inbox.