Through this abstract php class we can create our classes simply by extending this class
abstract class Singleton {
protected function __construct() {
}
final public static function getInstance( $calledClassName = null ) {
static $aoInstance = array();
if ( $calledClassName == null ) {
$calledClassName = get_called_class();
}
if (! isset ($aoInstance[$calledClassName])) {
$aoInstance[$calledClassName] = new $calledClassName();
}
return $aoInstance[$calledClassName];
}
final private function __clone() {
}
}
Example:
class DataBase extends Singleton {
[...]
}
$db = DataBase::getInstance();The problem we will encounter in PHP 5.2.x is that the function get_called_class does not exist, so we must have that function.
if(!function_exists('get_called_class')) {
class class_tools {
static $i = 0;
static $fl = null;
static function get_called_class() {
$bt = debug_backtrace();
if(self::$fl == $bt[2]['file'].$bt[2]['line']) {
self::$i++;
} else {
self::$i = 0;
self::$fl = $bt[2]['file'].$bt[2]['line'];
}
$lines = file($bt[2]['file']);
preg_match_all('
/([a-zA-Z0-9\_]+)::'.$bt[2]['function'].'/,
$lines[$bt[2]['line']-1],
$matches
);
$returnValue = $matches[1][self::$i];
// check if we call it from a call_user_func and similar
if ( empty( $returnValue )
&& isset( $bt[3]['function'] )
&& in_array($bt[3]['function'],array('call_user_func', 'call_user_func_array'))) {
$returnValue = $bt[3]['args'][0][0];
}
return $returnValue ;
}
}
function get_called_class() {
return class_tools::get_called_class();
}
}As you can see, it uses the debug_backtrace() function to determine which class we are calling. With this function we will no longer have problems when instantiating our “Singletons” in php.
Examples of usage that work perfectly in PHP 5.3, and now in PHP 5.2
$objeto = DataBase::getInstance() ;
[...]
$miClase = 'DataBase';
$objeto = call_user_func( array( $miClase, 'getInstance'));








Comments