二、抽象数据库接口(利用数据操作管理类)
在用mvc模式开发的时候,model层负责数据库的所有操作,为了对数据库的操作进行统一的管理,我们需要定义一个数据库操作管理类,由他来接替所有的数据库操作,也就是整个系统中只有这个数据库操作管理类,可以直接对数据库进行操作,如果其他的类需要对数据库进行操作,那它就必须调用和通过这个类来实现。
下面的db类就是一个这样的类。
<?php
/**************************************************************
* descript : mysql数据库操作管理类
*
* author : 大龄青年
* email :[email protected]
* qq : 303015292
* msn : [email protected]
*************************************************************/
/*
* example 1: 获取序列
* <?
* $db = new db();
* $result = $db->getseq('art_id', 2, 1);
* ?>
*/
/*
* example 2: 分页查询
* <?
* $db = new db();
* $result = $db->&querypage('select id,name from table', 2, 10, db_fetch_assoc);
* foreach($result as $row)
* echo $row['id'],'------'.$row['name'].'<br>';
* ?>
*/
/*
* example 3: 插入数据
* <?
* $db = new db();
* $result = $db->execute("insert into table (id, name) values(1,'name')");
* if($result>0) echo '插入数据成功';
* else echo '插入数据失败';
* ?>
*/
/*
* 定义数据库联接选项
* @var db_host string 数据库主机名称或地址
* @var db_name string 数据库名称
* @var db_user string 数据库用户名称
* @var db_pwd string 数据库用户的密码
* @var db_pconnect boolean 是否建立持久连接
*/
define('db_host', 'localhost');
define('db_name', 'test');
define('db_user', 'root');
define('db_pwd', '');
define('db_pconnect', true);
/*
*定义返回数据查询结果的类型
* @var db_fetch_assoc int 结果调用方式:$result['name']
* @var db_fetch_num int 结果调用方式:$result[0]
* @var db_fetch_both int 结果调用方式:$result['name'] 或 $result[0]
* @var db_fetch_object int 结果调用方式:$result->name
*/
define('db_fetch_assoc', 0);
define('db_fetch_num', 1);
define('db_fetch_both', 2);
define('db_fetch_object', 3);
/*
*定义默认序列发生器的名称
*/
define('db_sequence_tablename', 'sequences');
class db{
/*
* 当前数据库联接选项
*/
var $dbhost = db_host;
var $dbname = db_name;
var $dbtype = 'mysql';
var $dbuser = db_user;
var $dbpwd = db_pwd;
var $pcnn = db_pconnect;
/*
* 当前数据库连接
*/
var $cnn = '';
/*
* 数据查询结果的返回类型
*/
var $queryfetchtype = db_fetch_assoc;
/*
* 初始化函数
*/
function db(){
$this->cnn = ($this->pcnn? mysql_connect($this->dbhost, $this->dbuser, $this->dbpwd):
mysql_connect($this->dbhost, $this->dbuser, $this->dbpwd)) or
$this->_halt('数据库连接错误');
mysql_select_db($this->dbname, $this->cnn) or $this->_halt('数据库选择错误');
}
/*
* 数据查询函数
*
* @param $sql string 数据查询语句
* @param $fetchtype int 数据查询结果的返回类型
*
* @return array 数据查询结果
*/
function &query($sql, $fetchtype=db_fetch_assoc){
$data = array();
$rs = &mysql_query($sql, $this->cnn) or $this->_halt('数据查询错误', $sql);
$exe = $this->_getcommand($fetchtype);
while($row=&$exe($rs))
$data[] = &$row;
return $data;
}
/*
* 分页数据查询函数
*
* @param $sql string 数据查询语句
* @param $page int 当前预查询页码
* @param $pagesize int 每页显示多少条纪录
* @param $fetchtype int 数据查询结果的返回类型
*
* 数据查询结果,以及数据的分页信息
* @return array('pagesize' => 每页显示的条数
* 'recordcount' => 总纪录数
* 'pagecount' => 总页数
* 'page' => 当前页码
* 'isfirst' => 是否第一页
* 'islast' => 是否最后一页
* 'start' => 返回结果的第一条纪录的序号
* 'sql' => 查询的sql语句
* 'data' => 查询得到的数据结果
* )
* 数据查询结果,以及数据的分页信息
*/
function &querypage($sql, $page=1, $pagesize=20, $fetchtype=db_fetch_assoc){
$countsql = preg_replace('|select.*from|i','select count(*) count from', $sql);
$data['pagesize'] = (int)$pagesize<1? 20: (int)$pagesize;
$data['recordcount'] = $this->getone($countsql, 'count');
$data['pagecount'] = ceil($data['recordcount']/$data['pagesize']);
$data['page'] = $data['pagecount']==0? 0: ((int)$page<1? 1: (int)$page);
$data['page'] = $data['page']>$data['pagecount']? $data['pagecount']:$data['page'];
$data['isfirst'] = $data['page']>1? false: true;
$data['islast'] = $data['page']<$data['pagecount']? false: true;
$data['start'] = ($data['page']==0)? 1: ($data['page']-1)*$data['pagesize']+1;
$data['sql'] = $sql.' limit '.($data['start']-1).','.$data['pagesize'];
$data['data'] = &$this->query($data['sql'], $fetchtype);
return $data;
}
/*
* 进行数据查询只返回第 1 行的数据
*
* @param $sql string 数据查询语句
* @param $fetchtype int 数据查询结果的返回类型
*
* @return array 数据查询结果
*/
function &queryrow($sql, $fetchtype=db_fetch_assoc){
$rs = &mysql_query($sql, $this->cnn) or $this->_halt('单行数据查询错误', $sql);
$exe = $this->_getcommand($fetchtype);
return $exe($rs);
}
/*
* 进行数据查询只返回第 1 行第 n 列的数据
*
* @param $sql string 数据查询语句
* @param $field int 返回数据列的名称 或 数字序号
*
* @return string 返回单个字段的值
*/
function &getone($sql, $field = 0){
$rs = &mysql_query($sql, $this->cnn) or $this->_halt('单个数据查询错误', $sql);
$row = mysql_fetch_array($rs);
return $row[$field];
}
/*
* 进行sql语句,包含 delect / insert / update.....的执行语句
*
* @param $sql string 数据查询语句
*
* @return string 返回该语句影响的数据行数
*/
function execute($sql){
$rs = mysql_query($sql) or $this->_halt('语句执行错误', $sql);
return mysql_affected_rows($this->cnn);
}
/*
* 得到最后一次插入数据的编号
*/
function getinsertid(){
return mysql_insert_id($this->cnn);
}
/*
* 序列发生器,用来生成不重复的序列值
*
* @param $fieldname string 序列的名称
* @param $step int 序列号间隔
* @param $start int 序列号的起始数值
*
* @return int 新的序列值
*/
function getseq($fieldname, $step=1, $start=1){
$table = db_sequence_tablename;
$step = (int)$step;
$start = (int)$start;
$rs = mysql_query("update $table set seq_num=seq_num+($step) where seq_name='$fieldname'");
if(!$rs || mysql_affected_rows($this->cnn)<1){
$rs = mysql_query('select * from '.db_sequence_tablename, $this->cnn);
if(!$rs){
$sql = "create table $table (
seq_name varchar( 20 ) not null ,
seq_num bigint( 20 ) default 1 not null ,
primary key (seq_name))";
$rs = mysql_query($sql) or $this->_halt('创建序列发生器表失败', $sql);
}
$rs = mysql_query("insert into $table values('$fieldname', $start)") or
$this->_halt('添加新序列错误', $sql);
$seq = $start;
}else{
$seq = &$this->getone("select seq_num from $table where seq_name='$fieldname'");
}
return $seq;
}
function _getcommand($fetchtype){
switch($fetchtype){
case db_fetch_assoc: $exe = 'mysql_fetch_assoc'; break;
case db_fetch_num: $exe = 'mysql_fetch_row'; break;
case db_fetch_both: $exe = 'mysql_fetch_array'; break;
case db_fetch_object: $exe = 'mysql_fetch_object'; break;
default: $exe = 'mysql_fetch_array'; break;
}
return $exe;
}
function _halt($msg){
$errno = mysql_errno($this->cnn);
$errstr = mysql_error($this->cnn);
die("数据库错误:$msg<br> $errno : $errstr");
}
}
?>
新闻热点
疑难解答