PHP单例模式中的clone陷阱(原创)
说来惭愧,用PHP时间也不短了,居然一直不知道__clone成员方法的存在。
今天遇到,突然想起,我以前写得单例模式,有问题了!
单例模式类代码:
<?php class TestSingleton { private $sinVar = NULL; static private $testSingleton = NULL; private function __construct() { echo "Create Singleton Object Now!\n"; } static public function instance() { if (!(self::$testSingleton instanceof TestSingleton)) { self::$testSingleton = new TestSingleton(); } return self::$testSingleton; } // private function __clone() { // } public function setSinVar ($sinVar) { $this->sinVar = $sinVar; } public function getSinVar() { return $this->sinVar; } }
测试代码如下:
<?php require_once './testSingleton.php'; $singletonObj_a = TestSingleton::instance(); $singletonObj_b = TestSingleton::instance(); $singletonObj_c = clone $singletonObj_b; $singletonObj_a->setSinVar('singletonObj_a'); $singletonObj_b->setSinVar('singletonObj_b'); $singletonObj_c->setSinVar('singletonObj_c'); echo $singletonObj_a->getSinVar()."\n"; echo $singletonObj_b->getSinVar()."\n"; echo $singletonObj_c->getSinVar()."\n";
输出结果:
Create Singleton Object Now! singletonObj_b singletonObj_b singletonObj_c
说明,用clone之后,原来的单例模式代码,其实是可以编程多例的!!
不幸中的万幸,没有用过clone,所以Bug没有脱颖而出。
正确的办法就是把前面单例类的注释去掉,覆写一个私有的clone类,可以杜绝clone。