Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /share/CACHEDEV1_DATA/Web/www/libraries/UBBcode/text_parser.class.php on line 228

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /share/CACHEDEV1_DATA/Web/www/libraries/UBBcode/text_parser.class.php on line 228

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /share/CACHEDEV1_DATA/Web/www/libraries/UBBcode/text_parser.class.php on line 228
Extendable dataloading in PHP

Comments Blog About Development Research Sites

Extendable dataloading in PHP

Apr 9, 2009
There are a great many well-known code patterns out there. Most of those are generic, in that they can be used in many languages of roughly the same design (singleton's, fabric's, etc). However, PHP offers some unique features that are often overlooked by those more familiar with classic languages such as JAVA, C# or C++.

For those not familiar with PHP's awesome magic methods, I suggest you read this introduction first - it'll make the next code clearer.

Say you have a class, and wish to load additional data into that class. One can simply add data loading methods to that class, but eventually this means you're looking at a thousand lines of code in the untangible mess most senior programmers have come to known and dread. In PHP luckily, there is an easy alternative:

Code (php) (nieuw venster):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Abstract class InfoLoader {

  private
   $parent;            

  public function
__construct (Info & $parent) {
    $this -> parent   = & $parent;
    $this -> load();
  }


  public function
__set ($field, $value) {
    $this -> parent -> $field = $value;
  }
  

  public function
__get ($field) {
    return
$this -> parent -> $field;
  }


  abstract public function load ();
}


This is an abstract class that can be extended by all specific load classes, in an easy way:

Code (php) (nieuw venster):
1
2
3
4
5
6
7
8
class InfoSaloonTimes extends InfoLoader {
 
  private
   $times;
  
  public function
load () {
    if (
$this -> loadTimes())
      $this -> parseTimes();
  }

This is just a small part of a somewhat larger class (about ~80 lines total) that loads opening and closing times for hair saloons. You'll notice the load method has been implemented, thus making this a normal (non-abstract) class. Since the constructor in InfoLoader calls the load method, all one has to do to access the data loaded by this class is create a new object for it:
Code (php) (nieuw venster):
1
2
3
4
private function loadSaloonInfo () {
  new
InfoSaloonTimes($this);
  new
InfoSaloonDetails($this);
}


And that is basicly it! The classes obtain a reference to their parent, an Info object (see the constructor) which is then used to assign and request data from that parent. All requests for a public member are caught by the magic methods, so in the extending classes doing $this -> field = "hello world"; actually means the parent class gets a member field, which is then assigned the value "hello world". In effect, the data in public members is as easily accesable as if we would add all those methods to the main class itself, yet now it is all factorized in specific loader classes.

Advantages of this should be clear: we can enforce data-hiding using private members, the loader classes can easily be used by other objects as well, and the main class only needs a few dozen lines of code, instead of the hundreds it would otherwise require. There is a disadventage also unfortunately, in that extending classes cannot pass references to their own public members (since they are in effect owned by the parent class, not by themselfs), but that should be no more than a minor inconvenience - at worst, the parent class will have to pass the reference instead.

FragFrog out!

New comment

Your name:
Comment: