Singleton para PHP 5.3, y parche para 5.2

Singleton para PHP 5.3, y parche para 5.2

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'));

Relacionados