HomePHP Page 3 - Caching Result Sets in PHP: Implementing the Caching System in PHP 5
Traversing an array structure: developing an array Iterator - PHP
Welcome to the final part of the series “Caching Result Sets in PHP.” Hopefully, the last chapter of this tutorial will help you to put together all of the classes developed in the previous part, and demonstrate how the complete caching system can be implemented in a PHP 5 controlled environment.
Building an array Iterator is not a complex task at all. Specifically, the PHP5 SPL (Standard PHP Library) offers a new set of interfaces for implementing Iterators very easily (Iterator, ArrayIterator, and so on), so if you want to go deeper into the topic, visit the PHP site for detailed information.
In this case, I won’t use these interfaces for developing an array iterator, since they’re available only in PHP 5. For those developers using PHP 4, coding such a programming structure can be a didactical experience, before deciding to migrate to PHP’s latest version. However, if you’ve crossed the bridge to PHP 5, I strongly recommend using these existing interfaces.
Despite the fact that some of the common design patterns applied in software engineering are considered to be within the category of “advanced concepts,” having a decent knowledge of their theory and simple implementation in practical situations, helps you to know how to apply them in real conditions. Implementing the Iterator pattern to traverse a simple array structure may be as simple as this:
class arrayProcessor{ private $data; // data array for processing // constructor public function __construct($data=array()){ if(!is_array($data)){ throw new Exception('Invalid data array'); } $this->data=$data; } // get first array element public function getFirstElement(){ if(!$data=reset($this->data)){ throw new Exception('Error fetching first array element'); } return $data; } // get current array element public function getCurrentElement(){ if(!$data=current($this->data)){ return false; } return $data; } // get last array element public function getLastElement(){ if(!$data=end($this->data)){ throw new Exception('Error fetching last array element'); } return $data; } // get previous array element public function getPreviousElement(){ if(!$data=prev($this->data)){ return false; } return $data; } // get next array element public function getNextElement(){ if(!$data=next($this->data)){ return false; } return $data; } // reverse array elements function reverseElements($prekeys=true){ if(!$data=array_reverse($this- >data,$prekeys)){ throw new Exception('Error reversing array elements'); } return $data; } // sort array elements public function sortElements(){ if(!sort($this->data)){ throw new Exception('Error sorting array elements'); } return $this->data; } // get range of array elements public function getRange($offset,$length){ if(!$data=array_slice($this->data,intval ($offset),intval($length))){ throw new Exception('Error fetching range of elements'); } return $data; } // get random array element public function getRandomElement(){ if(!shuffle($this->data)){ throw new Exception('Error shuffling array elements'); } return $this->data[0]; } // search element in array public function searchElement($keyword){ return array_search($keyword,$this- >data); } // count array elements public function countElements(){ if(!$data=count($this->data)){ throw new Exception('Error counting array elements'); } return $data; } }
Although the code seems to be rather long, it’s quite simple to understand. It simply exposes the methods needed for performing different operations on an array structure. The class presents different methods for getting the current array element, or moving the array pointer back and forth. What’s more, we’re able to count, search and reverse array elements.
Since we’ve analyzed the logic of the “arrayProcessor” class, now the reason for using its methods within the “Cache” class should become clear. Because results sets are manipulated as associative arrays, it’s a matter of common sense to utilize an array Iterator for handling them. This is a simple topic, right?
All right, now we have seen in detail how these two classes establish a strong interaction and play a relevant role within the caching application.
I know that it's easy to say that using smaller and portable classes to build a bigger caching system leads to easier and faster implementation, but if you find yourself writing a large class that does “everything,” reconsider your design approach and start thinking of applications as separated blocks of reusable code that can be easily plugged into each other.
Keeping in mind these guidelines within application development, it’s time to put all of the classes together and assemble the whole caching system. Just click to the next page to learn how this is done.