使用 PHP 5.2.X 扩展单例
我在 PHP 5.2.6 上运行此代码
class Singleton {
static private $instance = false;
private $id = false;
protected function __construct() {
$this->id = uniqid();
}
static public function instance() {
if (!self :: $instance) {
self :: $instance = new self();
}
return self :: $instance;
}
public function get_id() {
return $this->id;
}
}
class Chucknorris extends Singleton {
}
echo "php version = ".phpversion()."<br>";
$singleton = Singleton::instance();
echo get_class($singleton)."<br>";
echo "singleton id = ".$singleton->get_id()."<br>";
$chucknorris = Chucknorris::instance();
echo get_class($chucknorris)."<br>";
echo "chucknorris id = ".$chucknorris->get_id()."<br>";
这是输出
php version = 5.2.6
Singleton
singleton id = 4ea7dca7d8f23
Singleton
chucknorris id = 4ea7dca7d8f23
当我请求 Chucknorris 的实例时,我总是得到 Singleton 实例。我想找到一种扩展单例的方法。
我知道我们可以使用 get_called_class 方法来做到这一点,但它仅在 PHP 5.3 中提供。无论如何,我是否可以扩展单例而无需在扩展类中重新定义设计模式?
I have this code running on PHP 5.2.6
class Singleton {
static private $instance = false;
private $id = false;
protected function __construct() {
$this->id = uniqid();
}
static public function instance() {
if (!self :: $instance) {
self :: $instance = new self();
}
return self :: $instance;
}
public function get_id() {
return $this->id;
}
}
class Chucknorris extends Singleton {
}
echo "php version = ".phpversion()."<br>";
$singleton = Singleton::instance();
echo get_class($singleton)."<br>";
echo "singleton id = ".$singleton->get_id()."<br>";
$chucknorris = Chucknorris::instance();
echo get_class($chucknorris)."<br>";
echo "chucknorris id = ".$chucknorris->get_id()."<br>";
Here's the output
php version = 5.2.6
Singleton
singleton id = 4ea7dca7d8f23
Singleton
chucknorris id = 4ea7dca7d8f23
When I ask for an instance of Chucknorris, I always get the Singleton one. I'd like to find out a way to extend the Singleton.
I know we can use get_called_class method to do it but it comes only with PHP 5.3. Is there anyway I can extend a Singleton without redefining the design pattern in the extended classes ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
PHP 的最佳选择5.3 是使用单例工厂:
这里唯一的缺点是你的单例构造函数是公共的..所以这是对该模式的基本违反。
更新:
这是一个删除公共构造函数的版本(警告:这会进入混乱/黑客/糟糕的设计领域)
Your best bet in PHP < 5.3 is to use a Singleton Factory:
The only downside here is that your Singleton constructor is public.. so that's a basic violation of that pattern.
Update:
Here's a version that removes the public constructor (warning: this is getting into messy/hacky/poor design territory)
如果 5.3 PHP 版本中不存在 get_class_function,为什么不模拟它呢?
这段代码可能会回答你的问题。
Why don't you simulate the get_class_function if it doesn't exist with 5.3 PHP version ?
This code may answer your question.
您可以在
Chucknorris
中重新定义getinstance
方法(以及实例本身)来获取它的实例而不是父实例,但我不确定您的目的是什么目标是。只需将扩展类更改为:这是您想要的吗?如果是这样——你想要它的原因是什么?我可以想到一些,但如果您分享您的目标,我会很高兴。
You can redefine just the
getinstance
method (and the instance itself) inChucknorris
to get an instance of it instead of the parent, but I'm not exactly sure what your end goal is. Just change the extending class to:Is this what you want? And if so - what is the reason you want it? I could think of a few, but would be glad if you share you goal.
如果您将
static private $instance = false;
移动到子类并使其受保护
而不是私有
,您的代码很可能会起作用。您还需要将
self::
替换为static::
,以便在子类中设置静态变量。这需要 PHP 5.3 - 但是,这应该不是问题,因为 PHP 5.2 自 2011 年 1 月起就已终止生命/支持(包括安全更新!)!
Your code will most likely work if you move
static private $instance = false;
to the subclass and make itprotected
instead ofprivate
.You also need to replace
self::
withstatic::
so the static var is set in the subclass.This requires PHP 5.3 - however, this shouldn't be a problem because PHP 5.2 reached end-of-life/support (that includes security updates!) as of january 2011!