View Single Post
Old 08-17-2008, 07:23 AM   #2 (permalink)
Theo
The Wanderer
 
Join Date: Aug 2008
Posts: 11
Thanks: 4
Theo is on a distinguished road
Default

I did think of another issue in this class. What if you want to pass in parameters on construction of a Singleton class? I'd argue against doing this as a Singleton is supposed to control its own construction, however it is possible to do:

PHP Code:
    //    The sole access point for singletons.
    
final public static function & GetInstance$inClass )
    {
        
//    Do we have one yet?
        
if( !array_key_exists$inClassself::$gInstances ) )
        {
            
self::$gInstances[$inClass] =& new $inClass;
            
            
//    Is this a singleton class?
            
if( !( self::$gInstances[$inClass] instanceof Singleton )
                || 
$inClass == 'Singleton' )
            {
                unset( 
self::$gInstances[$inClass] );
                throw new 
Exception"$inClass is not a Singleton class." );
            }
            
            
//    Get any extra arguments if any.
            
$theArguments func_get_args();
            
            
//    Remove the class name from the list.
            
array_shift$theArguments );
            
            
//    Call construct with any extra arguments passed in.
            
call_user_func_array
                
( array( self::$gInstances[$inClass], 'Construct' ),
                
$theArguments );
        }

        return 
self::$gInstances[$inClass];
    } 
We get the function arguments using func_get_args(). We then remove the first argument (this will be the class name). We then use call_user_func_array() to call the function and pass in any extra parameters passed into this function.

So with this test script:

PHP Code:
<?php

include_once( $_SERVER['DOCUMENT_ROOT'].'/../Include/Singleton.php' );

//    A test singleton with a 'Constructer'
class TestSingleton extends Singleton
{    
    function 
Construct$inVar1 null$inVar2 null )
    {
        echo <<<_TEXT_
Constructing...<br />
Var1 = 
$inVar1<br />
Var2 = 
$inVar2<br />
<br />
_TEXT_;
    }
    
    public 
$mVar;
}

//    Instantiate the Test Singleton.
$theTestSingleton Singleton::GetInstance'TestSingleton''Hello,''World!' );

?>
We get this output:

Quote:
Constructing...
Var1 = Hello,
Var2 = World!
A caveat is in order though: this kind of Singleton is created on first access. In more complicated scripts it can be difficult to determine exactly when a Singleton will be constructed. Always ensure that Singleton constructors have default values for all their parameters to prevent any warnings. Personally I'd choose to design my Singletons so they handle their own construction, which is kind of the point of Singletons anyway.
Theo is offline  
Reply With Quote