标签存档: Singleton

PHP 可继承的单例模式例子 Singleton

之前写单例模式,要为class定义一个singleton方法,每个用到单例模式的类都要定义,挺麻烦的,就考虑能否继承一个。 尝试了几个方法,能实现继承功能的,则不是严格意义上的单例模式了,后来找到PHP5.3后的get_called_class方法来实现。

/*
 * @Copyright (c) 2007,上海友邻信息科技有限公司
 * @All	rights reserved.
 *
 * 在 PHP 5.3 中有了get_called_class这个方法。
 *
 * @filename   Singleton.class.php
 * @category
 * @package
 * @author     Xinze
 * @date       2010-04-04 15:43:21
 */
/**
* Class and Function List:
* Function list:
* - __construct()
* - __clone()
* - getInstance()
* Classes list:
* - Singleton
*/

abstract class Singleton
{
    private static $_instance = array();

    protected function __construct()
    {
    }

    final private function __clone()
    {
    } 

    final public static function getInstance()
    {
        $called_class_name = get_called_class();

        if (!isset($_instance[$called_class_name]))
        {
            $_instance[$called_class_name] = new $called_class_name();
			$_instance[$called_class_name]->init();
        }

        return $_instance[$called_class_name];
    }

	public function init()
	{
	}
}

如果将代码放到PHP5.3之前的环境中运行,这个类则会出问题,如下这个函数可以解决通用问题:


if (!function_exists('get_called_class'))
{
    function get_called_class()
    {
        $bt = debug_backtrace();
        $l = 0;
        do
        {
            $l++;
            $lines = file($bt[$l]['file']);
            $callerLine = $lines[$bt[$l]['line'] - 1];
            preg_match('/([a-zA-Z0-9\_]+)::' . $bt[$l]['function'] . '/', $callerLine, $matches);

            if ($matches[1] == 'self')
            {
                $line = $bt[$l]['line'] - 1;

                while ($line > 0 && strpos($lines[$line], 'class') === false)
                {
                    $line--;
                }
                preg_match('/class[\s]+(.+?)[\s]+/si', $lines[$line], $matches);
            }
        }

        while ($matches[1] == 'parent' && $matches[1]);

        return $matches[1];
    }
}