mircobabini
6/7/2016 - 1:40 PM

singleton.class.php

<?php
/**
 * @version 2016-06-07
 */
class Singleton{
	public static function instance(){
		static $instances;

		$called_class = get_called_class();
		if( ! isset( $instances[ $called_class ] ) ){
			$instances[ $called_class ] = new static;
		}

		return $instances[ $called_class ];
	}
	public function classname(){
		return get_called_class();
	}
}

/**
 * Retro-support of get_called_class()
 * @author laurence(at)sol1(dot)com(dot)au
 */
if (!function_exists ('get_called_class'))
{
	function get_called_class ($bt = false, $l = 1)
	{
		if (!$bt) $bt = debug_backtrace ();
		if (!isset ($bt[$l])) throw new Exception ("Cannot find called class -> stack level too deep.");
		if (!isset($bt[$l]['type']))
		    throw new Exception ('type not set');
		else switch ($bt[$l]['type']) {
		    case '::':
		        $lines = file($bt[$l]['file']);
		        $i = 0;
		        $callerLine = '';
		        do {
		            $i++;
		            $callerLine = $lines[$bt[$l]['line']-$i] . $callerLine;
		        } while (stripos($callerLine,$bt[$l]['function']) === false);
		        preg_match('/([a-zA-Z0-9\_]+)::'.$bt[$l]['function'].'/',
		                    $callerLine,
		                    $matches);
		        if (!isset($matches[1])) {
		            // must be an edge case.
		            throw new Exception ("Could not find caller class: originating method call is obscured.");
		        }
		        switch ($matches[1]) {
		            case 'self':
		            case 'parent':
		                return get_called_class($bt,$l+1);
		            default:
		                return $matches[1];
		        }
		        // won't get here.
		    case '->': switch ($bt[$l]['function']) {
		            case '__get':
		                // edge case -> get class of calling object
		                if (!is_object($bt[$l]['object'])) throw new Exception ("Edge case fail. __get called on non object.");
		                return get_class($bt[$l]['object']);
		            default: return get_class($bt[$l]['object']);
		        }
		    default: throw new Exception ("Unknown backtrace method type");
		}
	}
}