的确global可以解决问题,也起到单例模式的作用,但在OOP中,我们拒绝这种编码。因为global存在安全隐患(全局变量不受保护的本质)。
全局变量是面向对象程序员遇到的引发BUG的主要原因之一。这是因为全局变量将类捆绑于特定的环境,破坏了封装。如果新的应用程序无法保证一开始就定义了相同的全局变量,那么一个依赖于全局变量的类就无法从一个应用程序中提取出来并应用到新应用程序中。
确切的讲,单例模式恰恰是对全局变量的一种改进,避免那些存储唯一实例的全局变量污染命名空间。你无法用错误类型的数据覆写一个单例。这种保护在不支持命名空间的PHP版本里尤其重要。因为在PHP中命名冲突会在编译时被捕获,并使脚本停止运行.....
<?php
/**
* MyPDO
* @author Jason.Wei <jasonwei06@hotmail.com>
* @license http://www.sunbloger.com/
* @version 5.0 utf8
*/
class
MyPDO
{
protected
static
$_instance
= null;
protected
$dbName
=
''
;
protected
$dsn
;
protected
$dbh
;
/**
* 构造
*
* @return MyPDO
*/
private
function
__construct(
$dbHost
,
$dbUser
,
$dbPasswd
,
$dbName
,
$dbCharset
)
{
try
{
$this
->dsn =
'mysql:host='
.
$dbHost
.
';dbname='
.
$dbName
;
$this
->dbh =
new
PDO(
$this
->dsn,
$dbUser
,
$dbPasswd
);
$this
->dbh->
exec
(
'SET character_set_connection='
.
$dbCharset
.
', character_set_results='
.
$dbCharset
.
', character_set_client=binary'
);
}
catch
(PDOException
$e
) {
$this
->outputError(
$e
->getMessage());
}
}
/**
* 防止克隆
*
*/
private
function
__clone() {}
/**
* Singleton instance
*
* @return Object
*/
public
static
function
getInstance(
$dbHost
,
$dbUser
,
$dbPasswd
,
$dbName
,
$dbCharset
)
{
if
(self::
$_instance
=== null) {
self::
$_instance
=
new
self(
$dbHost
,
$dbUser
,
$dbPasswd
,
$dbName
,
$dbCharset
);
}
return
self::
$_instance
;
}
/**
* Query 查询
*
* @param String $strSql SQL语句
* @param String $queryMode 查询方式(All or Row)
* @param Boolean $debug
* @return Array
*/
public
function
query(
$strSql
,
$queryMode
=
'All'
,
$debug
= false)
{
if
(
$debug
=== true)
$this
->debug(
$strSql
);
$recordset
=
$this
->dbh->query(
$strSql
);
$this
->getPDOError();
if
(
$recordset
) {
$recordset
->setFetchMode(PDO::FETCH_ASSOC);
if
(
$queryMode
==
'All'
) {
$result
=
$recordset
->fetchAll();
}
elseif
(
$queryMode
==
'Row'
) {
$result
=
$recordset
->fetch();
}
}
else
{
$result
= null;
}
return
$result
;
}
/**
* Update 更新
*
* @param String $table 表名
* @param Array $arrayDataValue 字段与值
* @param String $where 条件
* @param Boolean $debug
* @return Int
*/
public
function
update(
$table
,
$arrayDataValue
,
$where
=
''
,
$debug
= false)
{
$this
->checkFields(
$table
,
$arrayDataValue
);
if
(
$where
) {
$strSql
=
''
;
foreach
(
$arrayDataValue
as
$key
=>
$value
) {
$strSql
.=
", `$key`='$value'"
;
}
$strSql
=
substr
(
$strSql
, 1);
$strSql
=
"UPDATE `$table` SET $strSql WHERE $where"
;
}
else
{
$strSql
=
"REPLACE INTO `$table` (`"
.implode(
'`,`'
,
array_keys
(
$arrayDataValue
)).
"`) VALUES ('"
.implode(
"','"
,
$arrayDataValue
).
"')"
;
}
if
(
$debug
=== true)
$this
->debug(
$strSql
);
$result
=
$this
->dbh->
exec
(
$strSql
);
$this
->getPDOError();
return
$result
;
}
/**
* Insert 插入
*
* @param String $table 表名
* @param Array $arrayDataValue 字段与值
* @param Boolean $debug
* @return Int
*/
public
function
insert(
$table
,
$arrayDataValue
,
$debug
= false)
{
$this
->checkFields(
$table
,
$arrayDataValue
);
$strSql
=
"INSERT INTO `$table` (`"
.implode(
'`,`'
,
array_keys
(
$arrayDataValue
)).
"`) VALUES ('"
.implode(
"','"
,
$arrayDataValue
).
"')"
;
if
(
$debug
=== true)
$this
->debug(
$strSql
);
$result
=
$this
->dbh->
exec
(
$strSql
);
$this
->getPDOError();
return
$result
;
}
/**
* Replace 覆盖方式插入
*
* @param String $table 表名
* @param Array $arrayDataValue 字段与值
* @param Boolean $debug
* @return Int
*/
public
function
replace(
$table
,
$arrayDataValue
,
$debug
= false)
{
$this
->checkFields(
$table
,
$arrayDataValue
);
$strSql
=
"REPLACE INTO `$table`(`"
.implode(
'`,`'
,
array_keys
(
$arrayDataValue
)).
"`) VALUES ('"
.implode(
"','"
,
$arrayDataValue
).
"')"
;
if
(
$debug
=== true)
$this
->debug(
$strSql
);
$result
=
$this
->dbh->
exec
(
$strSql
);
$this
->getPDOError();
return
$result
;
}
/**
* Delete 删除
*
* @param String $table 表名
* @param String $where 条件
* @param Boolean $debug
* @return Int
*/
public
function
delete
(
$table
,
$where
=
''
,
$debug
= false)
{
if
(
$where
==
''
) {
$this
->outputError(
"'WHERE' is Null"
);
}
else
{
$strSql
=
"DELETE FROM `$table` WHERE $where"
;
if
(
$debug
=== true)
$this
->debug(
$strSql
);
$result
=
$this
->dbh->
exec
(
$strSql
);
$this
->getPDOError();
return
$result
;
}
}
/**
* execSql 执行SQL语句
*
* @param String $strSql
* @param Boolean $debug
* @return Int
*/
public
function
execSql(
$strSql
,
$debug
= false)
{
if
(
$debug
=== true)
$this
->debug(
$strSql
);
$result
=
$this
->dbh->
exec
(
$strSql
);
$this
->getPDOError();
return
$result
;
}
/**
* 获取字段最大值
*
* @param string $table 表名
* @param string $field_name 字段名
* @param string $where 条件
*/
public
function
getMaxValue(
$table
,
$field_name
,
$where
=
''
,
$debug
= false)
{
$strSql
=
"SELECT MAX("
.
$field_name
.
") AS MAX_VALUE FROM $table"
;
if
(
$where
!=
''
)
$strSql
.=
" WHERE $where"
;
if
(
$debug
=== true)
$this
->debug(
$strSql
);
$arrTemp
=
$this
->query(
$strSql
,
'Row'
);
$maxValue
=
$arrTemp
[
"MAX_VALUE"
];
if
(
$maxValue
==
""
||
$maxValue
== null) {
$maxValue
= 0;
}
return
$maxValue
;
}
/**
* 获取指定列的数量
*
* @param string $table
* @param string $field_name
* @param string $where
* @param bool $debug
* @return int
*/
public
function
getCount(
$table
,
$field_name
,
$where
=
''
,
$debug
= false)
{
$strSql
=
"SELECT COUNT($field_name) AS NUM FROM $table"
;
if
(
$where
!=
''
)
$strSql
.=
" WHERE $where"
;
if
(
$debug
=== true)
$this
->debug(
$strSql
);
$arrTemp
=
$this
->query(
$strSql
,
'Row'
);
return
$arrTemp
[
'NUM'
];
}
/**
* 获取表引擎
*
* @param String $dbName 库名
* @param String $tableName 表名
* @param Boolean $debug
* @return String
*/
public
function
getTableEngine(
$dbName
,
$tableName
)
{
$strSql
=
"SHOW TABLE STATUS FROM $dbName WHERE Name='"
.
$tableName
.
"'"
;
$arrayTableInfo
=
$this
->query(
$strSql
);
$this
->getPDOError();
return
$arrayTableInfo
[0][
'Engine'
];
}
/**
* beginTransaction 事务开始
*/
private
function
beginTransaction()
{
$this
->dbh->beginTransaction();
}
/**
* commit 事务提交
*/
private
function
commit()
{
$this
->dbh->commit();
}
/**
* rollback 事务回滚
*/
private
function
rollback()
{
$this
->dbh->rollback();
}
/**
* transaction 通过事务处理多条SQL语句
* 调用前需通过getTableEngine判断表引擎是否支持事务
*
* @param array $arraySql
* @return Boolean
*/
public
function
execTransaction(
$arraySql
)
{
$retval
= 1;
$this
->beginTransaction();
foreach
(
$arraySql
as
$strSql
) {
if
(
$this
->execSql(
$strSql
) == 0)
$retval
= 0;
}
if
(
$retval
== 0) {
$this
->rollback();
return
false;
}
else
{
$this
->commit();
return
true;
}
}
/**
* checkFields 检查指定字段是否在指定数据表中存在
*
* @param String $table
* @param array $arrayField
*/
private
function
checkFields(
$table
,
$arrayFields
)
{
$fields
=
$this
->getFields(
$table
);
foreach
(
$arrayFields
as
$key
=>
$value
) {
if
(!in_array(
$key
,
$fields
)) {
$this
->outputError(
"Unknown column `$key` in field list."
);
}
}
}
/**
* getFields 获取指定数据表中的全部字段名
*
* @param String $table 表名
* @return array
*/
private
function
getFields(
$table
)
{
$fields
=
array
();
$recordset
=
$this
->dbh->query(
"SHOW COLUMNS FROM $table"
);
$this
->getPDOError();
$recordset
->setFetchMode(PDO::FETCH_ASSOC);
$result
=
$recordset
->fetchAll();
foreach
(
$result
as
$rows
) {
$fields
[] =
$rows
[
'Field'
];
}
return
$fields
;
}
/**
* getPDOError 捕获PDO错误信息
*/
private
function
getPDOError()
{
if
(
$this
->dbh->errorCode() !=
'00000'
) {
$arrayError
=
$this
->dbh->errorInfo();
$this
->outputError(
$arrayError
[2]);
}
}
/**
* debug
*
* @param mixed $debuginfo
*/
private
function
debug(
$debuginfo
)
{
var_dump(
$debuginfo
);
exit
();
}
/**
* 输出错误信息
*
* @param String $strErrMsg
*/
private
function
outputError(
$strErrMsg
)
{
throw
new
Exception(
'MySQL Error: '
.
$strErrMsg
);
}
/**
* destruct 关闭数据库连接
*/
public
function
destruct()
{
$this
->dbh = null;
}
}
?>
<?php
require
'MyPDO.class.php'
;
$db
= MyPDO::getInstance(
'localhost'
,
'root'
,
'123456'
,
'test'
,
'utf8'
);
//do something...
$db
->destruct();
?>