Claudiu Persoiu

Blog-ul lui Claudiu Persoiu


Archive for the ‘Design patterns’ tag

Factory method pattern using PHP 5.3 and late static bindings

without comments

Factory method design pattern introduced by GoF (Gang of Four) which I’ve talked about in a previous blog, has the base idea of a method that generates objects. Most implementations are “poor”, because they use a lot of hard-coding for the factory (just like me in the previous blog).

PHP 5.3 offers the possibility of a very interesting implementation using “Late static bindings“.

The classes from which the objects will be generated are:

// abstract base class that will be inherited
abstract class Drink {

    // ingredients
    protected $ingredients;

    // public method for producing the drink
    abstract public function MakeDrink();
}

// a child class for tea
class Tea_Drink extends Drink {

    // ingredients for tea
    protected $ingredients = array('tea', 'sugar', 'mink', 'water');

    // make tea
    public function MakeDrink() {

        // make tea
    }
}

// another class for Bloody Mary
class BloodyMary_Drink extends Drink {

    // ingredients for Bloody Mary
    protected $ingredients = array('votka', 'salt', 'tomato juice');

    // make Bloody Mary
    public function MakeDrink() {

        // make BloodyMary

    }
}

The idea is to have an abstract factory class to extend as simple as possible when creating each new factory class.

PHP 5

In PHP 5 the class will look something like this:

// abstract Factory class
abstract class absFactory {

    // name of the base class
    static protected $base_class = '';

    // factory method
    public static function getInstance($type) {

        // name of the resulting class
        $class_name = $type . '_' . self::$base_class;

        // check if class exists
        // here you can add an autoloader
        if(!class_exists($class_name)) {
            throw new Exception( 'Class ' . $class_name . ' not loaded!');
        }

        // check to see if the class inherits the base class
        if(!is_subclass_of($class_name, self::$base_class)) {
            throw new Exception(
                'Class ' . $class_name . ' is not a child of ' . self::$base_class
            );
        }

        // new object
        return new $class_name;

    }

}

Because the getInstance() method is static the property will be static too.

If we try:

class DrinkFactory extends absFactory {

    static protected $base_class = 'Drink';
}

try {

    $obj = DrinkFactory::getInstance('Tea');

} catch (Exception $e) {

    echo $e->getMessage();
}

The output will be:

Class Tea_ not loaded!

Because of the “self”, we can’t just call the method using the child class because the value of $base_class will be “” and not “Drink”, we must overwrite the getInstance() method. Which is quite “complicated”.

A working version in PHP 5 will be:

class DrinkFactory extends absFactory {

    public static function getInstance($type) {

        self::$base_class = 'Drink';

        // factory method of the base factory class
        parent::getInstance($type);

    }

}

try {

    $obj = DrinkFactory::getInstance('Tea');

} catch (Exception $e) {

    echo $e->getMessage();
}

But is not exactly “elegant”.

PHP 5.3

Here we have “Late static bindings”, which is basically introducing the work “static”.

The base factory class will look something like this:

// abstract Factory class
abstract class absFactory {

    // name of the base class
    static protected $base_class = '';

    // factory method
    public static function getInstance($type) {

        // name of the resulting class
        $class_name = $type . '_' . static::$base_class;

        // check if class exists
        // here you can add an autoloader
        if(!class_exists($class_name)) {
            throw new Exception( 'Class ' . $class_name . ' not loaded!');
        }

        // check to see if the class inherits the base class
        if(!is_subclass_of($class_name, static::$base_class)) {
            throw new Exception(
                'Class ' . $class_name . ' is not a child of ' . static::$base_class
            );
        }

        // new object
        return new $class_name;

    }

}

The differences from the PHP 5 are marked with bold. A change so small allows us to create a much “nicer” factory class:

class DrinkFactory extends absFactory {

     static protected $base_class = 'Drink';

}

try {

    $obj = DrinkFactory::getInstance('Tea');

} catch (Exception $e) {

    echo $e->getMessage();
}

Basically in this version only the relevant property in this context is overwritten.

Written by Claudiu Persoiu

24 January 2010 at 5:46 PM

Posted in Design patterns,PHP

Tagged with , , ,

Factory method design patten in PHP

without comments

An creational design pattern, which represents an solution for generation objects without specifying the class name. Virtually all methods that generate objects are particular implementations of the Factory Method pattern.

Motivation:

A motivation for this choice is that the creation of the object is delegated to the factory method.

Diagram:

factory method pattern

Implementation:
The classes that generates the objects, the common class to extend and the class with the factory method:

// the common class to be extended
abstract class OutputBase {
     // output the necessary headers
     abstract public function header();

     // resulting body
     abstract public function body($data);

}

// class for XML ouput
class XMLOutput extends OutputBase {

     // output XML header
     public function header() {
          header('content-type: text/xml');
     }

     // xml document
     public function body($data) {
          $res = '';

          $res .= '';

          foreach ($data as $root => $item) {

               $res .= '';

               foreach ($item as $key => $val) {
                    $res .= '<'.$key.'>'.$val.'';
               }

               $res .= '';
          }

          $res .= '';

          return $res;

     }

}

// class for CSV output
class CSVOutput extends OutputBase {

     // output CSV header
     public function header() {
          header("Content-type: text/plain");
     }

     // CSV body
     public function body($data) {
          $res = '';

          $keys = array_keys($data[0]);

          foreach ($keys as $key) {
               $res .= '"'.$key.'";';
          }
          $res .= "\r\n";

          foreach ($data as $item) {
               foreach ($item as $val) {
                    $res .= '"'.$val.'";';
               }

               $res .= "\r\n";
          }

          return $res;
     }
}

// the factory method class
// is abstract so it wont be instantiated
abstract class OutputFactory {

     // constant for XML type
     const XML = 1;

     // constant for CSV type
     const CSV = 2;

     // static factory method
     public static function getInstance($type) {
          // depending which constant was received as a parameter
          // one of the objects will be returned
          switch ($type) {
               case self::XML :
                    return new XMLOutput();
               break;

               case self::CSV :
                    return new CSVOutput();
               break;
          }

          // if the value received as a parameter is not one of the constants
          // an exception will be thrown
          throw new Exception('Invalid class type!');
     }

}

Example:

// the data
$data = array(
               array(
                    'a' => 1,
                    'b' => 2,
                    'c' => 3
                    ),
               array(
                    'a' => 4,
                    'b' => 5,
                    'c' => 6
                    )
          );

// try-catch block in case of an exception
try {
     // generation the object
     $obj = OutputFactory::getInstance(OutputFactory::XML);

     // output headers
     $obj->header();

     // display body
     echo $obj->body($data);

} catch (Exception $e) {

     $e->getMessage();

}

Written by Claudiu Persoiu

23 January 2010 at 6:21 PM

Posted in Design patterns

Tagged with ,

Singleton pattern in PHP

without comments

Probably the most popular pattern form PHP and not only.

Motivation:

Restriction to a single instance of a resource across the app, accessible from anywhere.

Diagram:

singleton

Implementation:

The classic example for PHP is the database resource. The database connection must be unique across the app, not to establish multiple connections to the database and as a consequence resources to be wasted.

For a single instance to exist the constructor must only be accessible from a static method, and the resulting object must not have the posibillity to be cloned. Also the class must not be extensible.

Example:

// db connection information
define ( 'DB_HOST', 'localhost' );
define ( 'DB_USER', 'user' );
define ( 'DB_PASS', 'pass' );
define ( 'DB_DATABASE', 'db' );

/**
 * Singleton class for database connection management using mysqli
 */
final class SingletonDB {

     /**
      * Singleton instance
      *
      * @var SingletonDB
      */
     protected static $_instance = null;

     /**
      * Connection resource
      *
      * @var resource
      */
     protected $_connection = null;

     /**
      * Constructor which also connects to the database
      *
      */
     protected function __construct() {
          // connection to database server
          $this->_connection = new mysqli ( DB_HOST, DB_USER, DB_PASS );

          // in case of an error connection an exception is thrown
          if ($this->_connection->connect_error) {
               throw new Exception ( 'Error connection to mysql server' );
          }

          // selecting the database
          $this->_connection->select_db ( DB_DATABASE );

          // in case of an error selecting the database an exception is thrown
          if ($this->_connection->error) {
               throw new Exception ( 'Error selecting database' );
          }

     }

     /**
      * Run SQL queries
      *
      * @param string $query SQL query
      * @return mysqli_result
      */
     public function query($query) {
          return $this->_connection->query ( $query );
     }

     /**
      * Access for error messages
      *
      * @return string
      */
     public function error() {
          return $this->_connection->error;
     }

     /**
      * Method that is called when cloning an object
      * Is protected so is not possible to clone the object
      *
      */
     protected function __clone() {
     }

     /**
      * Close connection and destroy the object
      *
      */
     public function __destruct() {
          $this->_connection->close ();
     }

     /**
      * Method that returns an SingletonDB instance
      *
      * @return SingletonDB
      */
     public static function getInstance() {
          if (self::$_instance == null) {
               self::$_instance = new SingletonDB ( );
          }

          return self::$_instance;
     }
}

try {
     // SingletonDB instance
     $db = SingletonDB::getInstance ();

     // Query to be run
     $q = 'SELECT * FROM test';

     // the query will return an mysqli_result object
     $result = $db->query ( $q );

     // check for errors and display them
     if ($db->error ()) {

          echo $db->error ();

     } else {
          // extract the result and display
          while ( $row = $result->fetch_assoc () ) {
               var_dump ( $row );
          }
          // close mysqli_result object
          $result->close ();
     }
// in case of exception there is displayed
} catch ( Exception $e ) {
     echo $e->getMessage ();
}

Written by Claudiu Persoiu

10 October 2009 at 8:33 PM

Iterating objects using PHP and SPL

without comments

Iterator patter is probably the most popular pattern from SPL. Is a very simple way to demonstrate the advantages of an interface and SPL.

Motivation:
The possibility of iterating object type structures, using functions like foreach(), var_dump(), print_r() etc.

Diagram:

iterator diagram

Iterator structure:

In SPL there are a lot of interfaces and classes for iteration.

Iterator interface base structure:

/**
 * Iterator interface from SPL
 */
Iterator extends Traversable {
      /**
       * Returns the current element
       */
      abstract public mixed current ( void )

      /**
       * Returns the key of the current element
       */
      abstract public scalar key ( void )

      /**
       * Moves to the next element in the array
       */
      abstract public void next ( void )

      /**
       * Reset the iteration to the initial position
       */
      abstract public void rewind ( void )

      /**
       * Check to see if the current position is valid
       */
      abstract public boolean valid ( void )
}

Example 1:

A simple iterator object.

/**
 * The class for the iterator object
 */
class Iterabil implements Iterator {

	/**
	 * The index for the iterated element
	 */
	private $_current = 0;

	/**
	 * Array with elements to iterate
	 */
	private $_elements = array();

	/**
	 * Constructor
	 *
	 * @param array $elements Elements to iterate
	 */
	public function __construct($elements) {
		$this->_elements = $elements;
	}

	/**
	 * Current element
	 *
	 * @return mixed Current element
	 */
	public function current() {
		return $this->_elements[$this->_current];
	}

	/**
	 * Current index
	 *
	 * @return integer Current index
	 */
	public function key() {
		return $this->_current;
	}

	/**
	 * Move to the next index
	 */
	public function next() {
		$this->_current++;
	}

	/**
	 * Reset index
	 */
	public function rewind() {
		$this->_current = 0;
	}

	/**
	 * Check if the current element is set
	 *
	 * @return boolean If the current element is set
	 */
	public function valid() {
          return isset($this->_elements[$this->_current]);
     }
}

// class instance
$obj = new Iterabil(array(1, 2, 3, 4, 5));

// iterate object
foreach ($obj as $value) {
     echo $value.PHP_EOL;
}

// output:
// 1
// 2
// 3
// 4
// 5

Example 2:

Another example a little more complex, a class that allows to iterate through the public properties of a class which extends it. Iterator and Reflection are used.

/**
 * Class which iterates through the public properties of a class which extends it
 */
class Iterabil implements Iterator {

     /**
       * The index for the iterated element
       */
     private $_current = 0;

     /**
      * Array with elements to iterate
      */
     private $_elements = array();

     /**
      * Current element
      *
      * @return mixed Current element
      */
     public function current() {
          return $this->_elements[$this->_current]->name;
     }

     /**
      * Current index
      *
      * @return integer Current index
      */
     public function key() {
          return $this->_current;
     }

     /**
      * Move to next index
      */
     public function next() {
          $this->_current++;
     }

     /**
      * Reset index and get the properties
      */
     public function rewind() {
          // rewind is the first to be called
          // here the properties list should be obtained
          // ReflectionClass is initialized
          // with the current class name as a parameter
          $reflection = new ReflectionClass(get_class($this));

          // we get the public properties
          $this->_elements = $reflection->getProperties(ReflectionMethod::IS_PUBLIC);

          // set the current index
          $this->_current = 0;
     }

     /**
      * Check if the current element is set
      *
      * @return boolean If the current element is set
      */
     public function valid() {
         return isset($this->_elements[$this->_current]);
    }
}

/**
 * A new class with public properties
 *
 */
class Testing extends Iterabil {
     public $proprietate1;
     public $proprietate2;
}

// class instance
$obj = new Testing();

// iterate object
foreach ($obj as $value) {
     echo $value.PHP_EOL;
}

// output:
// proprietate1
// proprietate2

And if you what the above example to be accessible as an array you just have to implement ArrayAccess from SPL.

ArrayAccess structure:

ArrayAccess   {
    /**
     * Check if the offset exists
     */
    abstract public boolean offsetExists ( string $offset );

    /**
     * Returns the element of an offset or NULL if it does not exist
     */
    abstract public mixed offsetGet ( string $offset );

    /**
     * Set a value for an offset
     */
    abstract public void offsetSet ( string $offset , string $value );

    /**
     * Unset a value for an offset
     */
    abstract public void offsetUnset ( string $offset )
}

Example 3:

An even more complicated example which shows the power of interfaces from SPL. Iterator object accessible like an array.

To simplify the array access logic I’ve used the php native functions for iterating an array (next(), reset()).

/**
 * The class for the iterator object
 */
class Iterabil implements Iterator, ArrayAccess, Countable {

     /**
      * Array with elements to iterate
      */
     private $_elements = array();

     /**
      * Constructor
      *
      * @param array $elements Elementele de iterat
      */
     public function __construct($elements) {
          $this->_elements = $elements;
     }

     /**
      * Current element
      *
      * @return mixed Current element
      */
     public function current() {
          return current($this->_elements);
     }

     /**
      * Current index
      *
      * @return integer Current index
      */
     public function key() {
          return key($this->_elements);
     }

     /**
      * Move to the next index
      */
     public function next() {
          next($this->_elements);
     }

     /**
      * Reset index
      */
     public function rewind() {
          reset($this->_elements);
     }

     /**
      * Check if the current element is set
      *
      * @return boolean If the current element is set
      */
     public function valid() {
          return current($this->_elements)?true:false;
    }
    /**
     * Check if the offset exists
     *
     * @param string $offset Element key
     * @return boolean If the element is set
     */
    public function offsetExists($offset) {
         return isset($this->_elements[$offset]);
    }

    /**
     * Returns the element of an offset or NULL if it does not exist
     *
     * @param string $offset Array offset
     * @return mixed Element or NULL
     */
    public function offsetGet($offset) {
         return $this->_elements[$offset];
    }

    /**
     * Set a value for an offset
     *
     * @param string $offset Element offset
     * @param mixed $value Value of the element in the array
     */
    public function offsetSet($offset, $value) {
         $this->_elements[$offset] = $value;
    }

    /**
     * Unset a value for an offset
     *
     * @param string $offset Element offset
     */
    public function offsetUnset($offset) {
         unset($this->_elements[$offset]);
    }

    /**
     * Number of elements in the array
     *
     * @return integer Number of elements in array
     */
    public function count() {
         return count($this->_elements);
    }
}

// Class instance
$obj = new Iterabil(array(1, 2, 3, 4, 5));

echo 'Iteration using "for":'.PHP_EOL;

// iterate the object like a simple array
for($i = 0; $i < count($obj); $i++) {
     echo $obj[$i].PHP_EOL;
}

echo 'Element to delete: '.$obj[1].PHP_EOL;

unset($obj[1]);

echo 'Iteration using "foreach":'.PHP_EOL;

// iterate the object using foreach
foreach ($obj as $element) {
     echo $element.PHP_EOL;
}

// Output:
//Iteration using "for":
//1
//2
//3
//4
//5
//Element to delete: 2
//Iteration using "foreach":
//1
//3
//4
//5

Written by Claudiu Persoiu

8 October 2009 at 8:38 AM