最近重写了PHP中的数据库联接类,增加了分页的功能。
/**
?* FileName:db_mssql.class.php
?* Function:数据库连接类
?* Date:?? 2004-07-06?
?* Author:?? Kelphen
?* Modify: 修改了分页功能,对分页的设置和分页的条件进行了隐藏
?*/
class DB_MSSQL {
/**
?* 数据库服务器名称
?*
?* @var string
?* @access private
?*/
?var $Host???? = "";
/**
?* 数据库名称
?*
?* @var string
?* @access private
?*/
?var $Database = "";
/**
?* 数据库允许访问的用户
?*
?* @var string
?* @access private
?*/
?var $User???? = "";
/**
?* 数据库访问密码
?*
?* @var string
?* @access private
?*/
?var $Password = "";
/**
?* 连接数据库返回的连接号,连接成功则返回数据库的连接代号,失败返回 false 值
?*
?* @var string
?* @access private
?*/
?var $Link_ID? = 0;
/**
?* 执行SQL语句后返回的状态值,成功则返回true
?*
?* @var int
?* @access private
?*/
?var $Query_ID = 0;
/**
?* 存放记录集的数组
?*
?* @var array
?* @access private
?*/
?var $Record?? = array();
/**
?* 记录指针
?*
?* @var int
?* @access private
?*/
?var $Row????? = 0;
/**
?* 错误编号
?*
?* @var int
?* @access private
?*/
?var $Errno??? = 0;
/**
?* 错误信息
?*
?* @var string
?* @access private
?*/
?var $Error??? = "";
/**
?* 数据库连接资源的释放标志,如果$Auto_Free = 1则自动释放数据库资源
?*
?* @var int
?* @access private
?*/
?var $Auto_Free = 1;
/**
?* 数据库连接状态,如果$PConnect = 1则持续连接数据库
?*
?* @var int
?* @access private
?*/
?var $PConnect? = 0;
/**
?* 构造函数.有5个参数,其中$query可以省略.
?*
?* 用法:$db=&new DB_MSSQL("192.168.0.1","hello","kelphen","111111");
?*
?* @param $Host 数据库服务器名称
?* @param $Database 数据库名称
?* @param $User 用户名
?* @param $Password 数据库密码
?* @param $query SQL语句
?* @access public
?* @return void
?*
?*/
?function DB_MSSQL($Host,$Database,$User,$Password,$query = "") {
??$this->Host=$Host;
??$this->Database=$Database;
??$this->User=$User;
??$this->Password=$Password;
?}
/**
?* 数据库连接函数
?*
?* @access private
?* @return void
?*/
?function connect(){
??if( 0 == $this->Link_ID ){
???if(!$this->PConnect){
????$this->Link_ID = mssql_connect($this->Host, $this->User, $this->Password);
???}else{
????$this->Link_ID = mssql_pconnect($this->Host, $this->User, $this->Password);
???}
???if(!$this->Link_ID){
????$this->halt("数据库错误","connect($this->Host, $this->User, \$Password) failed.");
???}else{
????mssql_select_db($this->Database, $this->Link_ID);
???}
??}
?}
/**
?* 释放资源函数,释放query函数执行后所占用的资源
?*
?* @access private
?* @return void
?*/
?function free_result(){
??mssql_free_result($this->Query_ID);
??$this->Query_ID = 0;
?}
/**
?* 数据库查询函数,执行SQL语句,成功返回查询记录号,否则返回false
?*
?* 用法: $db->query($sql);
?* @param $Query_String
?* @access public
?* @return int
?*/
?function query($Query_String){
??if($Query_String == ""){
???return 0;
??}
??if(!$this->Link_ID){
???$this->connect();
??}
??$this->Query_ID = mssql_query($Query_String, $this->Link_ID);
??$this->Row = 0;
??//$this->Row = $this->seek($pos);
??if(!$this->Query_ID){
???$this->Errno = 1;
???$this->Error = "General Error (SQL SERVER 数据库不能返回详细的错误信息).";
???$this->halt("调试信息","无效的SQL语句: ".$Query_String);
??}
??return $this->Query_ID;
?}
/**
?* 取得当前记录数据,纪录集指针向下移动
?*
?* 用法: $db->next_record();
?* @access public
?* @return int
?*/
?function next_record(){
??if ($this->Record = mssql_fetch_row($this->Query_ID)){
???$count = mssql_num_fields($this->Query_ID);
???for ($i=0; $i<$count; $i++){
????$fieldinfo = mssql_fetch_field($this->Query_ID,$i);
????$this->Record[strtolower($fieldinfo->name)] = $this->Record[$i];
???}
???$this->Row += 1;
???$stat = 1;
??}else{
???if ($this->Auto_Free){
????$this->free_result();
???}
???$stat = 0;
??}
??return $stat;
?}
/**
?* 移动指针到指定行
?*
?* @param $pos
?* @access public
?* @return int
?*/
?function seek($pos){
??mssql_data_seek($this->Query_ID,$pos);
??if($pos!=""){
???$this->Row = $pos;
??}else{
???$this->Row=0;
??}
?}
/**
?* 查询数据库字段的信息
?*
?* @param $table
?* @access public
?* @return array
?*/
?function metadata($table){
??$count = 0;
??$id??? = 0;
??$res?? = array();
??$this->connect();
??$id = mssql_query("select * from $table", $this->Link_ID);
??if(!$id){
???$this->Errno = 1;
???$this->Error = "General Error (SQL SERVER 数据库不能返回详细的错误信息).";
???$this->halt("数据库错误","Metadata query 失败.");
??}
??$count = mssql_num_fields($id);
??for ($i=0; $i<$count; $i++){
???$info = mssql_fetch_field($id, $i);
???$res[$i]["table"] = $table;
???$res[$i]["name"]? = $info->name;
???$res[$i]["len"]?? = $info->max_length;
???$res[$i]["flags"] = $info->numeric;
??}
??return $res;
?}
/**
?* 取得插入的最后一个记录的主键值
?*
?* @access public
?* @return string
?*/
?function last_id(){
??$rsRows = mssql_query("Select @@IDENTITY as rows", $this->Link_ID);
??if ($rsRows){
???return mssql_result($rsRows, 0, "rows");
??}
?}
/**
?* 取得指定记录集的总数
?*
?* @access public
?* @return int
?*/
?function num_rows(){
??return mssql_num_rows($this->Query_ID);
?}
/**
?* 取得指定记录集的总数
?*
?* @access public
?* @return int
?*/
?function nf(){
??return $this->num_rows();
?}
/**
?* 打印指定记录集的总数
?*
?* @access public
?* @return int
?*/
?function np(){
??print $this->num_rows();
?}
/**
?* 取得指定记录集字段的数目
?*
?* @access public
?* @return int
?*/
?function num_fields(){
??return mssql_num_fields($this->Query_ID);
?}
/**
?* 取得指相应字段的数据
?*
?* @param $Field_Name 字段名
?* @access public
?* @return string
?*/
?function f($Field_Name){
??foreach ($this->Record as $key => $value){
???if($key==strtolower($Field_Name)){
????return $this->Record[strtolower($Field_Name)];
???}
??}
??$this->Errno = 3;
??$this->Error = "General Error (SQL SERVER 数据库字段错误信息).";
??$this->halt("数据库错误","列名".$Field_Name."无效");
?}
/**
?* 打印输出字段内容
?*
?* @param $Field_Name 字段名
?* @access public
?* @return void
?*/
?function p($Field_Name){
??print $this->f($Field_Name);
?}
/**
?* 设置错误信息
?*
?* @param $error_no 错误号
?* @param $error_title 错误标题
?* @access public
?* @return void
?*/
?function Set_Error($error_no,$error_title){
??$this->Errno=$error_no;
??$this->Error=$error_title;
?}
/**
?* 打印错误信息并强制系统停止运行
?*
?* @param $type 错误类型
?* @param $msg 错误信息
?* @access public
?* @return void
?*/
?function halt($type,$msg){
??printf("$type: %s
\n", $msg);
??printf("系统提示错误: %s (%s)
\n",$this->Errno,$this->Error);
??die("操作异常停止.");
?}
/**
?* 分页导航,直接调用此方法,对分页的设置进行隐藏.
?*
?* @access public
?* @void sting
?*/
?function getPageNavigation(){
??//初始化分页参数,做分页的准备
??$PrevPage=0;
??$NextPage=0;
??$StrPage="";
??//首页和上一页的链接
??if( $this->SumRows>1 && $this->Page>1){
???$PrevPage=$this->Page-1;
???$StrPage.=" ";
???$StrPage.=" dealPagePara("page=").">首页 ";
???$StrPage.=" dealPagePara("page=")." >上一页 ";
???$StrPage.="";
??}else{
???$StrPage.="首页 ";
???$StrPage.="上一页 ";
??}
??//下一页和末页的链接
??if( $this->Page>=1 && $this->Page<$this->MaxPage){
???$NextPage= $this->Page+1;
???$StrPage.=" ";
???$StrPage.=" dealPagePara("page=")." >下一页 ";
???$StrPage.=" MaxPage&".$this->dealPagePara("page=")." >末页 ";
???$StrPage.="";
??}else{
???$StrPage.=" 下一页 ";
???$StrPage.=" 末页 ";
??}
??$StrPage.=" 第 $this->Page 页,共 $this->MaxPage 页,共有 $this->SumRows 条记录";
??return $StrPage;
?}
/**
?* 处理分页条件参数,包括GET和POST
?*
?* @param $para_get 一般是page字符串
?* @access private
?* @void string
?*/
?function dealPagePara($para_get){
??if(sizeof($_POST)>0){
???foreach ($_POST as $key => $value) {
????//循环分析出$_POST变量的键值
????if (!empty($value)){
?????$para_post.=$key."=".urlencode($value)."&";
????}
???}
??}
??return ereg_replace($para_get."[0-9]+&*","",$GLOBALS["QUERY_STRING"].$para_post);
?}
/**
?* 最大页
?*
?* @var int
?* @access private
?*/
?var $MaxPage=0;
/**
?* 记录总数
?*
?* @var int
?* @access private
?*/
?var $SumRows=0;
/**
?* 每页记录数
?*
?* @var int
?* @access private
?*/
?var $Page_Size=0;
/**
?* 当前页
?*
?* @var int
?* @access private
?*/
?var $Page=0;
/**
?* 初始化分页参数,对数据集按照页的大小进行分块,做分页的准备
?*
?* @param??$page_size?每页的记录数量?
?* @param??$page??当前页,一般不用传递实参
?* @access??private
?* @return??boolean
?*/
?function setRecorderPointer($page_size,$page){
??$this->Page_Size=$page_size;
??$this->Page=$page;
??//记录总数量
??$this->SumRows=$this->num_rows();
??if($this->SumRows!=0){//如果记录总数不为0
???if($this->Page==0 or is_null($this->Page) or (!is_numeric($this->Page))){//所有非法页数都被设置为1
????$this->Page=1;
???}
???//获得记录总页数
???$this->MaxPage = (int)ceil($this->SumRows/$this->Page_Size);
???if((int)$this->Page > $this->MaxPage){//如果当前页大于总页数
????$this->Page=$this->MaxPage;
???}
???//移动记录集指针
???$this->seek(($this->Page-1)*$this->Page_Size);
??}else{//记录总数为0,返回false
???$this->Page=0;
???$this->MaxPage=0;
???return 0;
??}
?}
}
?>