Zend - The PHP Company




Miscellaneous

Add Code


Singleton  

Type: class
Added by: marcusbaker
Entered: 04/04/2002
Last modified: 04/12/2001
Rating: - (fewer than 3 votes)
Views: 4383
Allows creation of singleton classes by inheriting this superclass. The interface is the same as the GOF pattern. Handles constructor parameters, but as values only, but this can be easily worked arounded by overriding the instance() method.


<?php
    
//  singleton.php
    //
    //      Class that can only have one instance of itself.
    //  Repeated attempt to create new objects will fail unless
    //  using the instance() interface in which case the same
    //  object will be used each time.
    //
    //      This is a classic GOF pattern and follows that
    //  interface.
    //
    //  Usage:
    //
    //      To create a class that is a singleton...
    //
    //  class MyClass extends Singleton {
    //
    //      function MyClass(...) {
    //          $this->Singleton();
    //          ...
    //      }
    //
    //      ...
    //
    //      function &instance(...) {
    //          return Singleton::instance("MyClass", ...);
    //      }
    //  }
    //      The instance() method chaining is convenient, but unnecessary.
    //
    //      To create a singleton object...
    //
    //  $my1 = &MyClass::instance($my_params);
    //  $my2 = &Singleton::instance("MyClass", $my_params);
    //
    //      If you cannot put Singleton behaviour in the
    //  inheritance tree, then you can achieve a partial
    //  guarding effect as follows...
    //
    //  class MyClass extends Something {
    //      var $_guard;
    //
    //      function MyClass(...) {
    //          $this->_guard = &new Singleton("MyClass");
    //          ...
    //      }
    //
    //      ...
    //  }
    //
    //  Author: Marcus Baker
    //  Created: 13/8/2001
    //  PHP Version: Tested 4.1, 4.12. Should work on 4.06 as well.
    //  Copyright: Public domain, no warranty what so ever.
    //
    //  $Id$
    //
    //  Revisions...
    //      12/12/2001
    //  Rewritten for later versions of PHP.
    //  Registry library removed.
    //
    
if (!defined("SINGLETON_INCLUDED")) {
        
define("SINGLETON_INCLUDED""YES");

        
//  Singleton class.
        //
        //      Object that can only be instantiated once.
        //
        
class Singleton {
            var 
$_is_unique;                // Should be true if singleton valid.
   
            //  Singleton->Singleton() protected
            //
            //      Produces an error if the class already exists.
            //  Param:
            //      <string> $sClass        Class name to be registered.
            //                          Only necessary when using composition.
            //  Returns:
            //      <bool>         TRUE if OK.
            //  Notes:
            //      When including a singleton as a member, the holding
            //  object class name must be passed to the constructor.
            
function Singleton($class "") {
   
                if (
$class == "") {
                    
$class get_class($this);
                }

                
$registry = &Singleton::_get_registry();
                if (isset(
$registry[strtolower($class)])) {      // Class already exists.

                    
if (defined("SINGLETON_DUPLICATE_FATAL")) {
                        die(
"Attempt to create duplicate Singleton in class "".get_class($this).""");
                    }
                    
trigger_error("Attempt to create duplicate Singleton in class "".get_class($this)."""E_USER_ERROR);
                    
$this->_is_unique false;
                    return;
                }

                
$registry[strtolower($class)] = &$this;         // Stash self in the registry.
                
$this->_is_unique true;
            }

            
//  Singleton->instance() class public
            //
            //      Creates or fetches the only instance
            //  allowed of the class.
            //  Param:
            //      <string>       Class name.
            //      <...>          Constructor args. for object.
            //  Returns:
            //      <singleton>    Reference to new or existing object.
            
function &instance() {
        
                
// We need at least a class name in the arguments.
                //
                
$args func_get_args();
                if (
count($args) == 0) {      // No class name.
                    
trigger_error("Missing class name in Singleton::instance()"E_USER_ERROR);
                    return 
"";
                }

                
// The class name should be valid.
                //
                
$class array_shift($args);
                if (!
is_string($class) || !class_exists($class)) {      // Invalid class name.
                    
trigger_error("Invalid class name in Singleton::instance()"E_USER_ERROR);
                    return 
"";
                }

                
// Need to pass through other arguments to the new operator.
                //
                
$arg_labels = array();
                for (
$i 0$i count($args); $i++) {
                    
$arg_labels[$i] = "$args[$i]";
                }
                
$args_str implode(", "$arg_labels);      // Arguments as code string.

                // Check the singleton registry.
                //
                
$registry = &Singleton::_get_registry();
                if (isset(
$registry[strtolower($class)])) {
                    if (
count($args) > 0) {
                        
trigger_error("Cannot reinstantiate "$class" with new parameters in Singleton::instance()"E_USER_NOTICE);
                    }
                    return 
$registry[strtolower($class)]; 
                }

                
// Create and register the new class.
                //
                
eval("new $class($args_str);");
                return 
$registry[strtolower($class)]; 
            }

            
// Singleton->_get_registry() class private
            //
            //      Closure for the list of all singletons.
            // Param:
            //      None
            // Returns:
            //      <hash>      Reference to new or existing object.
            
function &_get_registry() {
                static 
$_registry;

                if (!isset(
$_registry)) {
                    
$_registry = array();
                }
                return 
$_registry;
            }

            
//  Singleton->is_unique() public
            //
            //      Accessor for state after construction.
            //  If true then this object is not the first one created.
            //  Param:
            //      None
            //  Returns:
            //    <hash>      Reference to new or existing object.
            
function is_unique() {

                return 
$this->_is_unique;
            }
        }
    }
?>


Usage Example




Rate This Script





Search



This Category All Categories