PHP
  Home arrow PHP arrow Page 4 - User-defined Interfaces in PHP 5: Introduction to Core Concepts
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
VPS Hosting  
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid  
Request Media Kit
Contact Us  
Site Map  
Privacy Policy  
Support  
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PHP

User-defined Interfaces in PHP 5: Introduction to Core Concepts
By: Alejandro Gervasio
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 12
    2005-12-19


    Table of Contents:
  • User-defined Interfaces in PHP 5: Introduction to Core Concepts
  • What are interfaces? Defining core concepts
  • The practical side: defining the “DeSerializer interface and “PostSaver” class
  • Making the Round Trip: defining the “MySQLCache” class
  • A functional example: using the “MySQLCache” and “PostSaver” classes

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article

     
     
    ADVERTISEMENT


    User-defined Interfaces in PHP 5: Introduction to Core Concepts - Making the Round Trip: defining the “MySQLCache” class
    ( Page 4 of 5 )

    Now that you know how to make a class implement an interface, I’m going to define the second class, “MySQLCache”, which caches MySQL results based on a time expiry trigger. Its source code is as following:

    // class MySQLCache
    class MySQLCache implements DeSerializer{
        private $host; // MySQL host
        private $user; // MySQL user
        private $password; // MySQL password
        private $database; // MySQL database
        private $query; // SQL query
        private $cacheFile; // cache file
        private $expiry; // expire time
        public function __construct($parameters=array()){
            if(count($parameters)<7){
                throw new Exception('Invalid number of parameters');
            }
            foreach($parameters as $parameter=>$value){
                if(!$parameter||!$value){
                    throw new Exception('Invalid connection
    parameters');
                }
                $this->{$parameter}=$value;
            }
        }
        // determine if cached data is valid
        private function isCacheValid(){
            if(file_exists($this->cacheFile)&&filemtime($this-
    >cacheFile)>(time()-$this->expiry)){
     return true;
            }
            return false;
        }
        private function readMySQL(){
            $this->connectDB();
            return $this->query();
        }
        private function connectDB(){
            if(!$this->conID=mysql_connect($this->host,$this-
    >user,$this->password,$this->database)){
                throw new Exception('Error connecting to MySQL');
            }
            if(!mysql_select_db($this->database,$this->conID)){
                throw new Exception('Error selecting database');
            }
        }
        private function query(){
            if(!$this->result=mysql_query($this->query)){
                throw new Exception('Error running query '.$this-
    >query);
            }
            while($row=mysql_fetch_array($this->result)){
                $data[]=$row;
            }
            $this->data=$data;
            $this->data=$this->getSerializedData();
            $this->writeCache();
            return $data;
        }
        private function writeCache(){
            // write cache file
            if(!$fp=fopen($this->cacheFile,'w')){
                throw new Exception('Error opening cache file');
            }
            // lock cache file
            if(!flock($fp,LOCK_EX)){
     throw new Exception('Unable to lock cache file');
            }
            // write serialized data to cache file
            if(!fwrite($fp,$this->data)){
                throw new Exception('Error writing to cache file');
            }
             // unlock cache file
            flock($fp,LOCK_UN);
            fclose($fp);
        }
        // read cache file
        private function readCache(){
            if(!$this->data=file_get_contents($this->cacheFile)){
                throw new Exception('Error reading cache file');
            }
            // return cached data
     return $this->getUnserializedData();
        }
        // unserialize data
        public function getUnserializedData(){
            return unserialize($this->data);
        }
        // serialize data
        public function getSerializedData(){
            return serialize($this->data);
        }
        // read data either from MySQL or cache file
        public function getData(){
            if(!$this->isCacheValid()){
                return $this->readMySQL();
            }
            else{
                return $this->readCache();
            }
        }
    }

    Despite the apparently-complicated look of the class, its rationale is fairly simple. Essentially, the tasks performed by the class can be subsumed in the following sequence: first, a MySQL result set is obtained through the “query()” method, once a successful connection has been established. Then, the result set is converted to an array and serialized by the “getSerializedData()” method. Finally, the serialized data is written to a specified cache file, which will be evaluated by the “isCacheValid()” method, in order to force a new cache generation when a given time expiry has been reached.

    As long as the cache is considered valid, data will be read from the given cache file. Otherwise, a new result set will be retrieved by running a SELECT statement and returned to the application as an array for further processing.

    Since the class’ logic is fairly understandable, I won’t spend a long time explaining its functionality. However I’d like to strongly point out the implementation of the “DeSerializer” interface within the class. Notice that again the “getSerializedData()” and “getUnserializedData()” are specifically defined within the class, to perform the serialize-unserialize sequence on the data. Although these methods basically perform the same tasks exposed within the first class “PostSaver”, they’re implemented in a different way, as you can appreciate through the lines below:

    // unserialize data
    public function getUnserializedData(){
        return unserialize($this->data);
    }
    // serialize data
    public function getSerializedData(){
        return serialize($this->data);
    }

    This condition is telling us that, despite the fact that both classes implement the same interface, the corresponding methods are defined differently. Therefore, the generic functionality defined through the interface is specifically implemented in different ways at class level. With reference to the example, there are two types of objects with nothing in common that use the same methods declared in the interface.

    The example shows clearly the differences in using subclasses derived from the same abstract parent class, due to the mere fact that each object belongs to a different family type. Otherwise, when working with a base parent class, child objects would be of the same type. In either case, as an implementer, it’s important that you know how to spot the difference.

    At this point, I have demonstrated the functionality of user-defined interfaces. However, in order to reaffirm the concepts that you just learned, I’ll write a couple of functional examples that demonstrate the usage of the previous classes. Thus, let’s get rid of the boring details and jump straight into the examples.



     
     
    >>> More PHP Articles          >>> More By Alejandro Gervasio
     

       

    PHP ARTICLES

    - Building Dynamic Queries with Chainable Meth...
    - PHP Encryption and Decryption Methods
    - Building a MySQL Abstraction Class with Meth...
    - Completing a Sample String Processor with Me...
    - Mastering WHILE Loops for PHP and MySQL
    - Method Chaining: Adding More Methods to the ...
    - Method Chaining in PHP 5
    - The Role of Interfaces in Applying the Depen...
    - Dependency Injection: Using a Setter Method ...
    - Using a Model Class with the Dependency Inje...
    - Injecting Objects Using Setter Methods with ...
    - Injecting Objects by Constructor with the De...
    - The Dependency Injection Design Pattern in P...
    - Performing Inferential Statistical Analysis ...
    - Performing Descriptive Statistical Analysis ...





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 1 Hosted by Hostway
    Stay green...Green IT