Introducing Static Members and Methods in PHP 5

Static properties and methods can be quite useful in a range of situations, not merely for constructing a Singleton class. This article, the first in a two-part series, introduces the basic concepts of static properties and methods, using plenty of hands-on examples.

Introduction

Since its official release, PHP 5 has gained wide acceptance among PHP developers around the world, particularly in those cases where the natural evolution of web programming requires working with a robust object model. Not surprisingly, modern PHP 5-based applications now make intensive use of the broad range of features included with the last incarnation of the language, which in general leads to building better-crafted application layers.

If you’ve been using the highly improved object model that comes with PHP 5 for a while, then you’ve possibly used static members and methods as an important part of your classes. This feature is very convenient to implement in those situations where a specific class member or method needs to be modified from outside the object context.

Although at first glance, static properties and methods seem to be a minor topic to consider, the truth is that they can be quite useful in specific cases. Of course, one of the most common occasions where both static members and methods can be properly exploited is when constructing a typical Singleton class, but there are other cases too. Therefore, if you’ve been using pattern-based programming for building your PHP programs, you’ll know what I’m talking about.

Considering the fairly huge range of applications where static properties and methods can be successfully used, in this two-part series, I’ll take an in-depth look at them. I will be introducing their basic concepts, as well as demonstrating their usage by copious hands-on examples.

Hopefully, by the end of this series you should be equipped with a decent knowledge of how to include static members and methods within your PHP applications with minor difficulties.

Want to know how the first chapter of this story begins? Click on the link below and keep reading. 

{mospagebreak title=Static members and methods: an example}

Indeed, a good way to start understanding how static class properties and methods work when used with PHP 5, is simply by setting up a comprehensive example, which also can be handy for grasping the logic behind static methods.

For this reason, below I coded a basic class, which shows in a friendly fashion how to use both static properties and methods in a PHP 5-controlled environment. Please, take a look at the signature of this class:

class Counter{    static private $counter=0; static public function incrementCounter(){ self::$counter++; return self::$counter; } }

Provided that you already examined the above class’ source code, then let me stress some key points regarding its definition. First off, this “Counter” class exposes a static “$counter” property, which is incremented each time the “incrementCounter()” method is called up.

However, one of the things worth noting here is how this method precisely increments the value of the mentioned property by using the “self” PHP keyword. Since this property has been initially declared static within the class, it shouldn’t be invoked with the pseudo variable $this, as you’d do normally with regular properties.

Now, once the previous “$counter” property has been properly explained, I’d like you to pay attention to the method responsible for incrementing it. As you can see, the method in question has been declared static too, therefore you’d be able to call it both from inside and outside the object context, as illustrated below:

$counter=new Counter; // call static method from inside object context echo $counter->incrementCounter(); // call method from outside object context echo Counter::incrementCounter();

As shown above, the mentioned “incrementCounter()” method can be invoked by using the conventional object context, that is with the “->” notation, or from outside this context, by using the (::) scope resolution operator. But after studying the prior script, probably one question keeps spinning in your mind: what’s the advantage of using the last approach?

Well, the answer is that a static method isn’t bounded to a specific class instance, which means that it can be called directly without having to create an object inside the application you’re developing. Pretty handy, isn’t it? After all, there are some situations where working with many objects can contribute to messing up an application’s source code, so static methods might be quite useful in those cases. 

All right, now you have a better idea of how to declare and use static properties and methods with PHP 5 by using the “static” keyword. However, you’ll agree with me that the sample class that you learned is rather simplistic for using in real situations. Therefore, in the following section you’ll learn how to use static methods and properties in a more useful case: applying the Singleton pattern.

To see how this design pattern will be used, please click on the link shown below and continue reading.

{mospagebreak title=Implementing the Singleton design pattern}

Undoubtedly, one of the typical cases where static members and methods are used conjunctly in the same class is when you’re implementing the Singleton pattern. As you probably know, this pattern allows you to work with only one instance of a given class, without having to get into trouble using multiple instances across the same application. This is a highly desirable feature generally required by seasoned developers.

However, I don’t want you to focus your whole attention on the pattern itself, since it’s out of the scope of this article. Instead, concentrate on the signature of the class below, so you can learn how a Singleton class can use both static properties and methods. Please look at the following class:

  // example of static property and method(uses the 'Singleton' pattern) class Singleton{ // declare static property static private $instance=NULL; private function__construct(){} // declare static method static public function getInstance(){        if(self::$instance==NULL){             self::$instance = new
Singleton() } return self::$instance; } } // return a new instance of 'Singleton' class $singA=Singleton::getInstance(); var_dump($singA); // return the same instance of 'Singleton' class $singB=Singleton::getInstance(); var_dump($singB);

Basically, the above class represents a classic definition of the Singleton pattern, where both static properties and methods are used together. In this case, the static “$instance” property is utilized as a flag to instruct the corresponding “getInstance()” method to return always a single instance of the class (hence the name Singleton), which helps with developing more robust code.

Also, it should be noticed that the proper “getInstance()” method has been declared static too, which means that it’s callable from outside the object content, as clearly demonstrated by the previous example (notice the use of the respective :: scope resolution operator). Indeed, a Singleton class is a great example for teaching how static members and methods can be used together in PHP.

Okay, I believe that the Singleton class that you just saw gave you a better understanding of how to code static properties and methods inside the same class. However, there’s a long way ahead of us when it comes to using them in PHP 5. That’s why in the course of the following section, I’ll be developing a brand new practical example, which will show you yet another case where static methods and properties are used conjunctly.

To continue reading and learn more, click on the link below.

{mospagebreak title=Building an array processing factory}

If you’ve been reading some of my PHP-related articles, published here on the prestigious Developer Shed network, then you’ll know that I’m a strong advocate of using hands-on examples for reaffirming concepts that are part of the unavoidable theory. For that reason, I’m going to show you another case where static methods and properties can be used together inside the same PHP application.

In short, let me explain the basics of the example that I plan to build: first off, I’ll create a few array handling classes, aimed at processing array elements in different ways. Then, with these classes well underway, I’ll define a generic array processing factory class, which will use a couple of static methods and properties to “fabricate” each of the array handling classes that I mentioned before.

Since this example seems pretty promising, I’ll begin by listing the set of array handling classes that I plan to use here. Below are the respective signatures of these classes:

// define abstract 'ArrayProcessor' class abstract class ArrayProcessor{ private $arrayFile; private $elements=array(); abstract function addArrayElement($element); abstract function processArray(); abstract function saveArray(); abstract function getArray(); } // define 'ArrayToUppercase' class class ArrayToUppercase extends ArrayProcessor{ public function__construct($arrayFile=
'default_path/array_data.txt') {if(!file_exists($arrayFile)) { throw newException
('Invalid array file!'); }        $this->arrayFile=$arrayFile; } public function addArrayElement($element){ if(!$element) { throw new Exception
('Invalid array element! Must be a non-empty value.'); }       $this->elements[]=$element; } // convert array elements to uppercase public function processArray(){        $this->elements=array_map
('strtoupper',$this->elements); } // save array elements to file public function saveArray(){       if(!$fp=fopen($this->arrayFile,'a+')){ throw new Exception
('Error opening array file');}        if(!fwrite($fp,serialize($this->elements))){ throw new Exception
('Error writing data to file');} fclose($fp); } // get array of elements public function getArray(){ return $this->elements; } // define 'ArrayToLowercase' class class ArrayToLowercase extends ArrayProcessor{ public function __construct
($arrayFile='default_path/array_data.txt'){         if(!file_exists($arrayFile)){ throw new Exception
('Invalid array file!'); }       $this->arrayFile=$arrayFile; } public function addArrayElement($element){ if(!$element) throw new Exception
('Invalid array element! Must be a non-empty value.'); }      $this->elements[]=$element; } // convert array elements to lowercase public function processArray(){        $this->elements=array_map
('strtolower',$this->elements); } // save array elements to file public function saveArray(){      if(!$fp=fopen($this->arrayFile,'a+')){ throw new Exception
('Error opening array file'); }     if(!fwrite($fp,serialize($this->elements))){ throw new Exception
('Error writing data to file'); } fclose($fp); } // get array of elements public function getArray(){ return $this->elements; } } // define 'ArrayToReverse'class class ArrayToReverse extends ArrayProcessor{ public function __construct
($arrayFile='default_path/array_data.txt') {        if(!file_exists($arrayFile)) { throw new Exception
('Invalid array file!'); }       $this->arrayFile=$arrayFile; } public function addArrayElement($element){ if(!$element){ throw new Exception
('Invalid array element! Must be a non-empty value.'); }         $this->elements[]=$element; } // reverse array elements public function processArray(){        $this->elements=array_reverse($this->elements); } // save array elements to file public function saveArray(){        if(!$fp=fopen($this->arrayFile,'a+')){ throw new Exception
('Error opening array file'); }         if(!fwrite($fp,serialize($this->elements))){ throw new Exception
('Error writing data to file'); } fclose($fp); } // get array of elements public function getArray(){ return $this->elements; } }

All right, after proceeding further, let me explain briefly what I’ve done until now. As you can see, first I defined an abstract base “ArrayProcessor” class. From this class I derived three different child classes, aimed at performing different operations on the corresponding array elements, such as lowercasing, uppercasing, and finally reversing them.

As you saw, all the classes that were created before have a “save()” method, which allows you to save the corresponding array elements to a given text file. The logic that drives these classes should be extremely easy to grasp.

At this point, and after defining the previous array processing classes, I’m sure you’re wondering… where do static properties and methods fit into this scenario? Well, I’m glad you asked! Because in the following section, I’ll be defining an array processor factory class, which not surprisingly will use the so-called static methods and members.

If you’re interested in learning how this factory class will look, please keep  reading.

{mospagebreak title=Building an array processor factory continued}

As I said before, an array processor factory is more than enough to demonstrate how static members and methods can be used in a helpful fashion. But how will this completely new class look?

To answer this question, here’s the definition for the mentioned class:

// define 'ArrayProcessorFactory' class (implements the Singleton pattern) class ArrayProcessorFactory{ private $allowedArrayProcessors=array
('ArrayToUppercase','ArrayToLowercase','ArrayToReverse'); static private $instance=NULL; private function__construct(){} // get instance of array factory static public function getInstance(){    if(self::$instance==NULL) {         self::$instance=new ArrayProcessorFactory(); } return self::$instance; } // create array processors public function createArrayProcessor($arrayProcessor){ if(!in_array($arrayProcessor,$this->
allowedArrayProcessors)){ throw new Exception
('Invalid name for array processor'); } return new $arrayProcessor; } }

As you can see, the above “ArrayProcessorFactory” class is indeed a factory that creates array processors, in accordance with the input passed to its “createArrayProcessor()” method. In this case, since I want to work only with a single instance of this class, I applied the definition of the Singleton pattern that you learned before to achieve this.

In addition, defining the factory class in this way implies using the static $instance property, along with the respective static “getInstance()” method that you saw in previous examples. Now, do you see how static members and methods play a relevant role in the context of the above factory class? I hope you do!

Okay, once the corresponding array processor factory has been defined, it’s time to see how it can be put to work. With reference to this subject, below I coded a short script that uses all the classes I defined earlier:

try{ // get single instance of 'ArrayProcessorFactory' class    $procFactory=ArrayProcessorFactory::getInstance(); // create 'ArrayToUppercase' object   $arrayUp=$procFactory->createArrayProcessor('ArrayToUppercase'); // create 'ArrayToLowercase' object     $arrayLow=$procFactory->createArrayProcessor('ArrayToLowercase'); // create 'ArrayToReverse' object     $arrayRev=$procFactory->createArrayProcessor('ArrayToReverse'); // add elements to first array     $arrayUp->addArrayElement('This is element 1');     $arrayUp->addArrayElement('This is element 2');   $arrayUp->addArrayElement('This is element 3');   $arrayUp->addArrayElement('This is element 4'); $arrayUp->addArrayElement('This is element 5'); // convert array to uppercase    $arrayUp->processArray(); // save array to file     $arrayUp->saveArray(); // print uppercased array     print_r($arrayUp->getArray()); // add elements to second array   $arrayLow->addArrayElement('This is element 1');   $arrayLow->addArrayElement('This is element 2');    $arrayLow->addArrayElement('This is element 3');    $arrayLow->addArrayElement('This is element 4');   $arrayLow->addArrayElement('This is element 5'); // convert array to lowercase     $arrayLow->processArray(); // save array to file    $arrayLow->saveArray(); // print uppercased array     print_r($arrayLow->getArray()); // add elements to third array     $arrayRev->addArrayElement('This is element 1'); $arrayRev->addArrayElement('This is element 2');   $arrayRev->addArrayElement('This is element 3');    $arrayRev->addArrayElement('This is element 4');   $arrayRev->addArrayElement('This is element 5'); // reverse array    $arrayRev->processArray(); // save array to file    $arrayRev->saveArray(); // print uppercased array    print_r($arrayRev->getArray()); } catch(Exception $e){ echo $e->getMessage(); exit(); }

As shown by the above script, I first used a single instance of the factory class –please examine the implementation of the “getInstance()” method — in order to create different array processor objects. Then, I populated the pertinent arrays with some trivial values, which were processed and saved appropriately via the corresponding “processArray()” and “save()” methods respectively, and finally the results were outputted to the browser as follows:

Array ( [0] => THIS IS ELEMENT 1 [1] => THIS IS ELEMENT 2 [2] =>
THIS IS ELEMENT 3 [3] => THIS IS ELEMENT 4 [4] => THIS IS ELEMENT 5 ) Array ( [0] => this is element 1 [1] => this is element 2 [2] =>
this is element 3 [3] => this is element 4 [4] => this is element 5 ) Array
( [0] => This is element 5 [1] => This is element 4 [2] => This is element 3 [3] => This is element 2 [4] => This is element 1 )

The output shown above clearly demonstrates how both static methods and properties can be used conjunctly to apply, in the correct sequence, the Singleton and Factory patterns. As usual, feel free to tweak all code samples listed here, so you can acquire a better grounding in using static members and methods with PHP.

Bottom Line

In this first part of the series, you learned the basics of defining static members and properties with PHP 5, and used them in concrete cases, such as the implementation of the Singleton and Factory patterns respectively.

However this instructive journey has just started. That’s why in the next tutorial, I’ll show you how to expand the application of static methods in PHP 5, demonstrating how they can be used for interacting with MySQL.

If you wish to find out how this will be done, don’t miss the next part!

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

chat sex hikayeleri Ensest hikaye