PHP单例模式中的clone陷阱(原创)

原文链接:http://www.cnblogs.com/maodouzi/archive/2010/06/15/1758502.html

  说来惭愧,用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。

转载于:https://www.cnblogs.com/maodouzi/archive/2010/06/15/1758502.html

展开阅读全文
博主设置当前文章不允许评论。

[原创]SQLServer陷阱

06-10

本文旨在指出一些在使用SQLServer过程中容易犯的错误, 希望能给您带来帮助.rn若没有特殊说明, 本文是指在MS SQLServer 2000简体中文版的默认配置环境中.rnrn一, NULL与布尔数据类型rnTransact-SQL中存在Boolean类型, if 后面的表达式的计算结果一般是Boolean类型, 但无法使用 declare 定义Boolean类型的变量.rnrnBoolean数据类型有三种取值, TRUE, FALSE, UNKNOWN, 第3种取值通常会被人忽视从而导致逻辑错误.rn默认情况下SET ANSI_NULLS为ON, 在逻辑表达式中如果你忽略了NULL的存在, 结果可能会异于你所想.rn例1: rn[code=SQL]rndeclare @a intrnif (@a > 0)rn set @a = 1rnelse if not (@a > 0)rn set @a = 2rnelsern set @a = 3rn[/code]rn结果@a的值应该是3, 因为NULL>0的值为UNKNOWN, NOT UNKNOWN的值还为UNKNOWN.rn例2:rn[code=SQL]rndeclare @a intrnif @a = nullrn set @a = 1rnelse if @a = null or 1 = 1rn set @a = 2rnelsern set @a = 3rn[/code]rn结果@a的值应该是2, 因为NULL = 0的值为UNKNOWN, UNKNOWN or TRUE的值为TRUE.rnrn二, 运行时错误与自动回滚事务rn有些人认为一个批查询在执行中发生了错误, 这个查询就会中止, 其实是错误的.rnrn例1:rn[code=SQL]rndeclare @i intrnset @i = 1 / 0rnset @i = 1rnselect @irn[/code]rn结果会先报一个rn服务器: 消息 8134,级别 16,状态 1,行 2rn遇到被零除错误。rn然后输出结果集 1.rnrn例2:rn[code=SQL]rnset xact_abort onrndeclare @i intrnset @i = 1 / 0rnset @i = 1rnselect @irn[/code]rn结果只报错, 不会输出结果.rnrn例3:rn请在查询分析器中新建连接执行rn[code=SQL]rncreate table table1(id int primary key)rnrnbegin tranrninsert into table1 values (1)rninsert into table1 values (1)rninsert into table1 values (2)rncommit tranrn[/code]rn第二个insert会产生违反主键约束错误, 但是执行结束后你会发现事务已经提交并且table1中已经有两行记录1与2rnrn例4:rn[code=SQL]rnset xact_abort onrnrncreate table table2(id int primary key)rnrnbegin tranrninsert into table2 values (1)rninsert into table2 values (1)rninsert into table2 values (2)rncommit tranrn[/code]rn执行结束后, table2中没有记录, 说明事务已经回滚.rnrn当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。编译错误rnrn(如语法错误)不受 SET XACT_ABORT 的影响。rn一般批查询中 SET XACT_ABORT 默认为 OFF, 隐式开启的事务如触发器中SET XACT_ABORT 默认为ONrnrn未完... 论坛

没有更多推荐了,返回首页