Mediante esta clase abstracta de php podremos crear nuestras clases simplemente extendiendo esta clase
-
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() {
-
}
-
}
Ejemplo:
-
-
class DataBase extends Singleton {
-
[…]
-
}
-
-
$db = DataBase::getInstance();
El problema que nos encontraremos en PHP 5.2.x es que no existe la función get_called_class por lo que deberemos tener esa función.
-
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];
-
// comprobamos si lo llamamos desde un call_user_func y 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();
-
}
-
}
Como se puede ver utiliza la funcion debug_backtrace() para determinar a que clase estamos llamando. Con esta función ya no tendremos problemas a la hora de instanciar nuestros “Singleton” en php.
Ejemplos de uso que funcionan perfectamente en PHP 5.3, y ahora en PHP 5.2
-
$objeto = DataBase::getInstance() ;
-
[…]
-
$miClase = 'DataBase';
-
$objeto = call_user_func( array( $miClase, 'getInstance'));
Se comenta por aquí