之前写单例模式,要为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];
}
}
近期评论