Home arrow PHP arrow Page 2 - The Get_called_class() Function in PHP 5.3

Review: using Late Static Binding to implement the registry pattern - PHP

In this third part of a series on late static bindings, you will learn how to use the “get_called_class()” function bundled with PHP 5.3 for determining at runtime which class has been called in a static context. In certain situations this function can be used as a replacement for late static bindings, but LSB has a wider range of possible uses; keep this in mind when developing your own object-oriented applications.

TABLE OF CONTENTS:
  1. The Get_called_class() Function in PHP 5.3
  2. Review: using Late Static Binding to implement the registry pattern
  3. Using the get called class function
  4. Putting the registry classes into action
By: Alejandro Gervasio
Rating: starstarstarstarstar / 2
May 19, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

As usual, before I start digging deeper into the use of the “get_called_class()” function referenced in the introduction, I'm going to take a brief look at the example developed in the last part of the series. It demonstrated how to take advantage of the functionality offered by late stating bindings to implement a basic hierarchy of registry classes.

With that said, here’s the source code corresponding to the first of these classes, which defines the structure and partial behavior of a generic registry. Here it is:

(RegistryAbstract.php)

abstract class RegistryAbstract

{

    protected static $_instances = array();

   

    // get Singleton instance of the registry

    public static function getInstance()

    {

        // the static call to 'getClass()' is resolved at runtime

        $class = static::getClass();

        if (!isset(self::$_instances[$class]))

        {

            self::$_instances[$class] = new $class;

        }

        return self::$_instances[$class];

    }

   

    // throw an exception as this class can't be instantiated

    protected static function getClass()

    {

        throw new RegistryException('This class is abstract and cannot be instantiated!');

    }

   

    // implemented by registry subclasses

    abstract public function set($key, $value);

   

    // implemented by registry subclasses

    abstract public function get($key);

   

    // implemented by registry subclasses

    abstract public function clear();         

}

(RegistryException.php)

<?php

class RegistryException extends Exception{}

As you can see, the “RegistryAbstract” class is nothing but a basic Singleton that declares a few intuitive methods which should be implemented by flyweight registries. Of course, the most relevant section of this class is the definition of “getInstance(),” which utilizes late static bindings to resolve at runtime calls to the static “getClass()” method.

To help you understand the inner workings of this process more clearly, here’s a subclass derived from the previous abstract parent that can be used for saving and retrieving data from an internal array. Check it out:    

(ArrayRegistry.php)

<?php

class ArrayRegistry extends RegistryAbstract

{

    private $_data = array();

   

    // save data to the registry

    public function set($key, $value)

    {

        $this->_data[$key] = $value;

        return $this;

    }

   

    // get data from the registry

    public function get($key)

    {

        return isset($this->_data[$key]) ? $this->_data[$key] : null;

    }

    // get called class

    public static function getClass()

    {

        return __CLASS__;

    }

    // clear the registry

    public function clear()

    {

        $this->_data = array();

      }        

}

To be frank, the only thing worth noting about the above “ArrayRegistry” class is that it overrides the inherited “getClass()” method to return an instance of itself to client code. With this concrete registry already set, the next thing we need to do is create a basic autoloader that includes the previous classes automatically. Here’s one that performs that task pretty decently:

(Autoloader.php)

<?php

class Autoloader

{

    private static $_instance;

   

    // get Singleton instance of the autoloader

    public static function getInstance()

    {

       if (!self::$_instance)

       {

           self::$_instance = new self;

       }

       return self::$_instance; 

    }

   

    // private constructor

    private function __construct()

    {

        spl_autoload_register(array($this, 'autoload')); 

    }

   

    // prevent cloning instance of the autoloader

    private function __clone(){}

   

    // autoload classes on demand

    public static function autoload($class)

    {

        $file = $class . '.php';

        if (!file_exists($file))

        {

            require_once 'FileNotFoundException.php';

            throw new FileNotFoundException('The file containing the requested class was not found.');

        }

        require $file;

        unset($file);

        if (!class_exists($class, false))

        {

            require_once 'ClassNotFoundException.php';

            throw new ClassNotFoundException('The requested class was not found.');

        }

    }  

}

(FileNotFoundException.php)

<?php

class FileNotFoundException extends Exception{}

(ClassNotFoundException.php)

<?php

class ClassNotFoundException extends Exception {}

Understanding the logic that drives the previous autoloader is a straightforward process, so for the sake of brevity I’m not going to waste your time explaining how it works. Instead, I suggest you look at the following code fragment, which shows how to use all of the classes coded before in a quite useful way:

<?php

try

{

    require_once 'Autoloader.php';

    // grab the Singleton instance of the autoloader

    $autoloader = Autoloader::getInstance();

    // grab the Singleton instance of the ArrayRegistry class

    $arrayRegistry = ArrayRegistry::getInstance();

    // save some users to the registry

    $arrayRegistry->set('user1', 'Julie Smith')->set('user2', 'Mary Wilson');

    // get the last user from the registry

    echo $arrayRegistry->get('user2');

    /*

    displays the following

    Mary Wilson

    */

}

catch (Exception $e)

{

    echo $e->getMessage();

    exit();

}

Admittedly, this script isn’t the most useful piece of code that you’ll find on the web, but it shows a couple of things worth noticing here: first, it’s extremely simple to implement a hierarchy of Singleton registries, and last but not least, this has been accomplished thanks to the use behind the scenes of late static bindings.

Even though this feature can be used to do many clever things in a static context other than creating flyweight registries, the truth is that there are certain use cases where it can be replaced directly by the “get_called_class()” function mentioned at the beginning of this tutorial. This function is in reality an equivalent of LSB, as it allows you to retrieve the name of the class from which a static method has been called. This is identical to the statement “static::getClass()” coded within the “getInstance()” method that you saw a moment ago.

To demonstrate how to work with this function, in the coming section I’m going to modify the definitions of the previous registry classes, which this time will use the function in question to do their business.

To learn the full details of this process, jump ahead and read the lines to come.



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

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: