Handling Static Data with PHP 5

It’s pretty common when using PHP to develop dynamic, object-oriented applications. Every so often, though, you need to work with static data. This article will explain how to work with static data and static properties, and show you how this ability can be useful in real-world situations.

Introduction

When you start learning some of the most important concepts for using the object-oriented paradigm with PHP, you quickly realize the remarkable benefits of building classes and objects, defining their methods and properties, and working with aggregation and composition as well.

Of course, things get interesting when you begin applying the pillars of object-based programming, such as inheritance and polymorphism. At that point you’ve already acquired a decent background in developing dynamic, object-oriented PHP applications. I purposely used the term "dynamic" because it implies the existence of one or more classes that perform different tasks and output "dynamic" results.

However, while defining a bunch of dynamic methods for a given class certainly is one of the most common process that a PHP developer has to tackle on a frequent basis, the truth is that the powerful object model offered by PHP 5 allows you to work with static data too, in a very approachable fashion. But, in the context of PHP programming…what does static data mean?

Well, in simple terms, when a method of a class is declared static, it can be called from outside the object context, just like a conventional PHP function, thus avoiding the direct instantiation of that particular class. Pretty useful, right?

Besides, there’s more good news on the horizon, since PHP 5 does let you work with static properties, which means that when a class property is declared static, then it will be unique for the entire class, in this way being callable from outside the object context, and also shared by all the instances of that specific class.

Perhaps, if you reread the above sentences, you may find the concept of working with static data in PHP 5 rather hard to grasp, or even pointless, but the truth is that in real world situations, this feature can be extremely useful. Therefore, and assuming that the subject of this series has already caught your attention, in this group of tutorials I’ll be taking a close look at creating and using static properties and methods with PHP 5, and also provide you with numerous hands-on examples so you can acquire a solid grounding in this important topic.

Are you ready to learn how to declare and use static data with PHP 5? Then don’t you stay static; begin reading now!

{mospagebreak title=Building dynamic web page DIVs}

A good place to start demonstrating the remarkable functionality of working with static class methods in PHP 5 is with developing a basic web application. This application’s primary goal is to display on the browser a certain number of dynamic DIVs as part of a simple web page.

In this situation, since the number of DIVs that need to be built across different web documents may vary, it would be highly desirable to define a class that spawns as many DIVs as required via the implementation of a static factoring method. But I’m getting ahead of myself, so first let me show you the signatures of the PHP classes that return to client code, the appropriate (X)HTML markup required to display a basic DIV.

Having explained that, these DIV rendering classes look like this:

// define abstract ‘DivElement’ class
abstract class DivElement{
  private $id;
  private $class;
  private $content;
  abstract public function __construct($content=’This is the
content for the DIV element.’,$id=’divid’,$class=’divclass’);
  abstract public function display();          
}

// define concrete ‘AbsoluteDivElement’ class
class AbsoluteDivElement extends DivElement{
  public function __construct($content=’This is the content for
the DIV element.’,$id=’divid’,$class=’divclass’){
    if(!$content){
      throw new Exception(‘Invalid content for the DIV element’);
    }
    if(strlen($id)>16||!preg_match("/[a-z]/",$id)){
      throw new Exception(‘Invalid ID attribute for the DIV
element.’);
    }
    if(strlen($class)>16||!preg_match("/[a-z]/",$class)){
      throw new Exception(‘Invalid class attribute for the DIV
element.’);
    }
    $this->content=$content;
    $this->id=$id;
    $this->class=$class;     
  }

  public function display(){
    $html='<div';
    if($this->id){
      $html.=’ id="’.$this->id.’"';
    }
    if($this->class){
      $html.=’ class="’.$this->class.’"';
    }
    $html.=’ style="position: absolute;top: 100px;left:
10px;">’.$this->content.'</div>';
    return $html;
  }          
}

// define concrete ‘LeftFloatedDivElement’ class
class LeftFloatedDivElement extends DivElement{
  public function __construct($content=’This is the content for
the DIV element.’,$id=’divid’,$class=’divclass’){
    if(!$content){
      throw new Exception(‘Invalid content for the DIV element’);
    }
    if(strlen($id)>16||!preg_match("/[a-z]/",$id)){
      throw new Exception(‘Invalid ID attribute for the DIV
element.’);
    }
    if(strlen($class)>16||!preg_match("/[a-z]/",$class)){
      throw new Exception(‘Invalid class attribute for the DIV
element.’);
    }
    $this->content=$content;
    $this->id=$id;
    $this->class=$class;     
  }

  public function display(){
    $html='<div';
    if($this->id){
      $html.=’ id="’.$this->id.’"';
    }
    if($this->class){
      $html.=’ class="’.$this->class.’"';
    }
    $html.=’ style="float: left;">’.$this->content.'</div>';
    return $html;
  }          
}

// define concrete ‘RightFloatedDivElement’ class
class RightFloatedDivElement extends DivElement{
  public function __construct($content=’This is the content for
the DIV element.’,$id=’divid’,$class=’divclass’){
    if(!$content){
      throw new Exception(‘Invalid content for the DIV element’);
    }
    if(strlen($id)>16||!preg_match("/[a-z]/",$id)){
      throw new Exception(‘Invalid ID attribute for the DIV
element.’);
    }
    if(strlen($class)>16||!preg_match("/[a-z]/",$class)){
      throw new Exception(‘Invalid class attribute for the DIV
element.’);
    }
    $this->content=$content;
    $this->id=$id;
    $this->class=$class;     
  }

  public function display(){
    $html='<div';
    if($this->id){
      $html.=’ id="’.$this->id.’"';
    }
    if($this->class){
      $html.=’ class="’.$this->class.’"';
    }
    $html.=’ style="float: right;">’.$this->content.'</div>';
    return $html;
  }          
}

As you can see, the business logic implemented by the above PHP classes is very easy to follow. First I built an abstract "DivElement" class for defining the generic structure of a DIV container, and then derived from it three concrete classes. These new classes are tasked with returning to client code the required markup to display an absolutely-positioned DIV, along with others that are left and right-floated respectively.

So far, so good, right? At this stage I defined a few simple classes that display DIV elements on a given web page. The question that comes up now is the following: how can a static method be used in a useful fashion in conjunction with all of these recently created classes?

Well, as I expressed earlier, the best way to take advantage of the functionality encapsulated within the previous DIV classes rests on defining a factory mechanism, which allows the spawning of as many DIVs as required. Thus, here’s where the implementation of a static method comes in, since the factory will use a method of this type to create a certain number of DIV objects.

However, all of these interesting tasks will be carried out in the following section, thus click on the link that appears below and keep reading to learn more.

{mospagebreak title=Factoring DIVs using both conventional and dynamic methods}

As you’ll certainly recall from the prior section, my intention here is to demonstrate how a static method can be really useful in certain cases, particularly when it’s necessary to spawn a determined number of objects, but without having to create an instance of the factory class that builds the objects in question. This concept is perfectly applicable to all of the DIV classes that were defined previously, so let me show you a comparative example where two different factory classes are used to instantiate a few DIV objects, first by using a conventional factoring method, and then by using a static method.

Having said that, here is the signature of the first factory class, which in this case defines a conventional factoring method for spawning some DIV objects:

// define ‘DivFactory’ class – no static method is used in this
case
class DivFactory{

  public function createDiv
($type,$content,$id=’defaultID’,$class=’defaultClass’){
    if($type!=’AbsoluteDivElement’&&$type!
=’LeftFloatedDivElement’&&$type!=’RightFloatedDivElement’){
      throw new Exception(‘Invalid object name for being
created.’);
    }
    return new $type($content,$id,$class);
  }
}

As you can see, the previous class has only one factory method, called "createDiv()", which is responsible for returning to client code a specific type of DIV object. Obviously, the method is callable from inside the object context, which implies that it can be used easily to instantiate some basic DIV objects, as indicated below: 

try{

  // use ‘DivFactory’ class to spawn some div objects – no static
method is used (poor implementation since factory class instance
is created)
  $divFactory=new DivFactory;
  $divs=array($divFactory->createDiv(‘AbsoluteDivElement’,’This
is the content of the absolutely-positioned DIV
element’),$divFactory->createDiv(‘LeftFloatedDivElement’,’This is
the content of the left-floated DIV element’),$divFactory-
>createDiv(‘RightFloatedDivElement’,’This is the content of the
right-floated DIV element’));

  // display DIV elements on the browser
  foreach($divs as $div){
    echo $div->display();
  }
}
catch(Exception $e){
  echo $e->getMessage();
  exit();
}

If you study the previous code sample, then you’ll realize that its implementation is rather inefficient, since it creates an unnecessary instance of the factory class to spawn three different DIV objects, which are finally used to display the real containers on the browser via their "display()" method.

Quite possibly, at this very moment you’re wondering what’s wrong with creating an instance of the factory class. Actually, not much, but this approach can be improved if a static factory method is used instead of a conventional one.

To help you understand this concept, below I redefined the previous factory class in such a way that it now uses a static method to create instances of the three DIV objects that were shown in the prior section.

The signature of this improved factory class is as follows:

// define ‘DivFactory’ class – static method is used
class DivFactory{

  public static function createDiv
($type,$content,$id=’defaultID’,$class=’defaultClass’){
    if($type!=’AbsoluteDivElement’&&$type!
=’LeftFloatedDivElement’&&$type!=’RightFloatedDivElement’){
      throw new Exception(‘Invalid object name for being
created.’);
    }
    return new $type($content,$id,$class);
  }
}

As shown above, the factory class looks nearly the same as the one in all the previous examples. Of course, the only difference here is the declaration of its factoring method static. This means that it can be perfectly callable from outside the object context, thus avoiding the unnecessary instantiation of the pertinent factory class. Pretty neat, right?

To reaffirm this concept, below I listed an example that shows how to spawn three different DIV objects, without using any instance of the factory class in question:

// use ‘DivFactory’ class to spawn some div objects – factory
method is called statically, so no factory class instance is
created
try{
  $divs=array(DivFactory::createDiv(‘AbsoluteDivElement’,’This is
the content of the absolutely-positioned DIV
element’),DivFactory::createDiv(‘LeftFloatedDivElement’,’This is
the content of the left-floated DIV
element’),DivFactory::createDiv(‘RightFloatedDivElement’,’This is
the content of the right-floated DIV element’));

  // display divs elements on the browser
  foreach($divs as $div){
    echo $div->display();
  }
}
catch(Exception $e){
  echo $e->getMessage();
  exit();
}

See how useful it is to utilize a static method to create the previous DIV objects? I guess you do! Please, notice how the aforementioned DIVs are properly spawned by calling statically the corresponding "createDiv()" method. In this case, hopefully I provided you with a concrete example where a static method is used in a helpful fashion for implementing the popular factory pattern.

All right, at this stage I’m sure that you already have an accurate idea of how to take advantage of the remarkable functionality provided by static methods in PHP 5. In the next section of this tutorial I’ll be listing the source code of all the classes built here, so you can use them to develop your own testing examples.

Click on the link below and keep reading, please.

{mospagebreak title=Putting all the classes together}

As I promised in the section that you just read, below are the respective definitions for all the sample classes that I created here, so you can have them at your disposal if you may want to use them to improve your existing skills for using static methods with PHP 5.

That being said, here are the aforementioned classes:

// define abstract ‘DivElement’ class
abstract class DivElement{
  private $id;
  private $class;
  private $content;
  abstract public function __construct($content=’This is the
content for the DIV element.’,$id=’divid’,$class=’divclass’);
  abstract public function display();          
}

// define concrete ‘AbsoluteDivElement’ class
class AbsoluteDivElement extends DivElement{
  public function __construct($content=’This is the content for
the DIV element.’,$id=’divid’,$class=’divclass’){
    if(!$content){
      throw new Exception(‘Invalid content for the DIV element’);
    }
    if(strlen($id)>16||!preg_match("/[a-z]/",$id)){
      throw new Exception(‘Invalid ID attribute for the DIV
element.’);
    }
              if(strlen($class)>16||!preg_match("/[a-
z]/",$class)){
      throw new Exception(‘Invalid class attribute for the DIV
element.’);
    }
    $this->content=$content;
    $this->id=$id;
    $this->class=$class;     
  }

  public function display(){
    $html='<div';
    if($this->id){
      $html.=’ id="’.$this->id.’"';
    }
    if($this->class){
      $html.=’ class="’.$this->class.’"';
    }
    $html.=’ style="position: absolute;top: 100px;left:
10px;">’.$this->content.'</div>';
    return $html;
  }          
}

// define concrete ‘LeftFloatedDivElement’ class
class LeftFloatedDivElement extends DivElement{

  public function __construct($content=’This is the content for
the DIV element.’,$id=’divid’,$class=’divclass’){
    if(!$content){
      throw new Exception(‘Invalid content for the DIV element’);
    }
    if(strlen($id)>16||!preg_match("/[a-z]/",$id)){
      throw new Exception(‘Invalid ID attribute for the DIV
element.’);
    }
    if(strlen($class)>16||!preg_match("/[a-z]/",$class)){
      throw new Exception(‘Invalid class attribute for the DIV
element.’);
    }
    $this->content=$content;
    $this->id=$id;
    $this->class=$class;     
  }

  public function display(){
    $html='<div';
    if($this->id){
      $html.=’ id="’.$this->id.’"';
    }
    if($this->class){
      $html.=’ class="’.$this->class.’"';
    }
    $html.=’ style="float: left;">’.$this->content.'</div>';
    return $html;
  }          
}

// define concrete ‘RightFloatedDivElement’ class
class RightFloatedDivElement extends DivElement{
  public function __construct($content=’This is the content for
the DIV element.’,$id=’divid’,$class=’divclass’){
    if(!$content){
      throw new Exception(‘Invalid content for the DIV element’);
    }
    if(strlen($id)>16||!preg_match("/[a-z]/",$id)){
      throw new Exception(‘Invalid ID attribute for the DIV
element.’);
    }
    if(strlen($class)>16||!preg_match("/[a-z]/",$class)){
      throw new Exception(‘Invalid class attribute for the DIV
element.’);
    }
    $this->content=$content;
    $this->id=$id;
    $this->class=$class;     
  }

  public function display(){
    $html='<div';
    if($this->id){
      $html.=’ id="’.$this->id.’"';
    }
    if($this->class){
      $html.=’ class="’.$this->class.’"';
    }
    $html.=’ style="float: right;">’.$this->content.'</div>';
    return $html;
  }          
}

// define ‘DivFactory’ class
class DivFactory{
  public static function createDiv
($type,$content,$id=’defaultID’,$class=’defaultClass’){
    if($type!=’AbsoluteDivElement’&&$type!
=’LeftFloatedDivElement’&&$type!=’RightFloatedDivElement’){
      throw new Exception(‘Invalid object name for being
created.’);
    }
    return new $type($content,$id,$class);
  }
}

Final thoughts

As you saw, in this first tutorial of the series I demonstrated how to use static methods in PHP 5 to perform a pretty useful task — creating DIVs to be displayed on a given web page. Naturally, this concept can be easily extended to other PHP applications that require the implementation of the factory pattern as well, so all the examples shown here should be educational enough to point you in the right direction. 

In the next part of the series, I’ll be covering another important topic surrounding the use of static data with PHP 5, more specifically concerning the utilization of static properties in concrete situations.

Now that you know what the next part will cover, you won’t want to miss it!

[gp-comments width="770" linklove="off" ]

chat