php mysql pdo 类_php pdo mysql数据库操作类

  • Post author:
  • Post category:php


namespace iphp\core;useiphp\App;/**

* 数据库操作基类 基于pdo

* @author xuen

* 支持链式操作,支持参数绑定

* 说明1 只有在绑定了参数后,pdo才会自动处理单引号。

* 说明2 关闭连接时,要设置pdo null

* 说明3 在脚本处理完后,最好手动关闭连接。不然mysql并不一定会关闭连接。

*@example

* $res=$db->findAll(array(

‘field’=>’ID,albumName,albumImage,

mainActor,directors,tags,info,area,

keywords,wflag,year,mod_version,totalDuration’,

‘where’=>$where,

‘order’=>’flag desc,hit_count desc’,

‘limit’=>”{$limit[‘offset’]},{$limit[‘pagesize’]}”

));

$res=$db->field(‘ID,stitle,jisu,liuchang,gaoqing,chaoqing,

totalDuration,bTime,eTime’)

->where($where)

->limit(“{$limit[‘offset’]},{$limit[‘pagesize’]}”)

->findAll();*/

final classMyDb

{private $pdo;public $tableName;//表名

private $sql;//当前执行的SQL语句

public $error=”;//当前执行sql的错误消息

public $prefix=”;//前缀

public $charset=’utf8′;public $sqlQuery=array(‘field’=>’*’,

‘where’=>’1’,

‘join’=>”,

‘group’=>”,

‘having’=>”,

‘order’=>”,

‘limit’=>”,

‘union’=>”,

‘params’=>array()

);public $fields=array();//得到当前表所有的字段名称

private static $_instance=array();protected $dbName;//用户名

protected $username;private $k;//密码

protected $password;//主机名

protected $host;//端口号

protected $port;//一个时间戳,表示当前链接在什么时候过期,过期后,将重建一个对象。

protected $expireTime;//PDO链接属性数组

protected $attr=array(//这个超时参数,实际上mysql服务器上的配置为准的。这里用于什么时候重建对象

//说明如是设置了这个参数,如果不显式的将pdo设为null,可能造成连接资源在mysql上不被释放。

\PDO::ATTR_TIMEOUT=>30,\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_SILENT,\PDO::ATTR_ORACLE_NULLS=>\PDO::NULL_NATURAL,

//如果设置了这个参数为true,inndob,需要手动commit

//\PDO::ATTR_AUTOCOMMIT=>false,

\PDO::ATTR_DEFAULT_FETCH_MODE=>\PDO::FETCH_ASSOC,\PDO::ATTR_PERSISTENT=>FALSE);/**

* 构造方法

* @param array $config 配置文件

* @param array $attr 数组选项*/

private function __construct($config,$attr)

{//索引数组合并不能使用merge

foreach ($this->attr as $key=>$row)

{if(isset($attr[$key]))$this->attr[$key]=$attr[$key];

}$this->pdo=new \PDO($config[‘dsn’], $config[‘username’],

$config[‘password’],$this->attr);if(isset($config[‘prefix’]) && $config[‘prefix’]!=”)$this->prefix=$config[‘prefix’];if(isset($config[‘charset’]) && $config[‘charset’]!=”)$this->charset=$config[‘charset’];$this->pdo->exec(“set names {$this->charset}”);//保存当前数据库名称,主机,端口。

preg_match(‘/dbname=(\w+)/’, $config[‘dsn’],$ma);preg_match(‘/host=(.*?);/’, $config[‘dsn’],$ma1);preg_match(‘/port=(\w+)/’, $config[‘dsn’],$ma2);$this->dbName=$ma[1];$this->host=$ma1[1];$this->port=$ma2[1]?$ma2[1]:3306;$this->username=$config[‘username’];$this->password=$config[‘password’];//设置链接过期时间

$timeout=$this->attr[\PDO::ATTR_TIMEOUT];$this->expireTime=time()+$timeout;

}private function__clone(){}/**

* @param $config

* @param array $attr

* @return \iphp\core\MyDb*/

static public function getInstance($config,$attr=array())

{if(!is_array($config))$config=App::getApp()->getConfig($config);$k=md5(implode(”, $config));//如果连接没有创建,或者连接已经失效

if( !(static::$_instance[$k] instanceof self))

{static::$_instance[$k]=new self($config,$attr);static::$_instance[$k]->k=$k;

}//如果连接超时。

elseif(time()>static::$_instance[$k]->expireTime)

{static::$_instance[$k]->close();static::$_instance[$k]=new self($config,$attr);static::$_instance[$k]->k=$k;

}return static::$_instance[$k];

}/**

*

* @param unknown_type $tableName

* @return $this*/

public function tableName($tableName)

{$this->tableName=$this->prefix.$tableName;//$this->setField();

return $this;

}/**

* @return \PDO*/

public functiongetPdo()

{return $this->pdo;

}/**

* 得到当前sql语句,并完成参数替换

* @return string*/

public functiongetSql()

{return $this->sql;

}/**

* @param string $sql

* @return bool*/

public function findAll($sql=”)

{$stmt=$this->query($sql);if(!$stmt)return false;return $stmt->fetchAll();

}/**

* @param string $sql

* @return bool*/

public function findOne($sql=”)

{$this->sqlQuery[‘limit’]=1;$stmt=$this->query($sql);if($stmt===false)return false;return $stmt->fetch();

}/**

* 根据主键查找记录

* @param mixed $ids

* @return 返回一维或二维数组*/

public function find($ids)

{$num=count(explode(‘,’, $ids));$this->setField();if($num==1)

{$res= $this->where(“{$this->fields[$this->tableName][‘pk’]}='{$ids}'”)->findOne();

}else{//如果是字符串主键,要加引号

$tmp=explode(‘,’, $ids);$tmp=array_map(function($item){return “‘”.$item.”‘”;

}, $tmp);$ids=implode(‘,’, $tmp);$res= $this->where(“{$this->fields[$this->tableName][‘pk’]} in ({$ids})”)->findAll();

}return $res;

}/**

* 插入数据的方法,自动完成参数绑定

* @param array $data 一维数组 array(Field=>value)

* @return boolean | int*/

public function insert($data)

{$this->setField();$params=array();$field=array();$placeholder=array();foreach($data as $key=>$row)

{//删除非法字段信息

if(!in_array($key, $this->fields[$this->tableName]))continue;$params[‘:’.$key]=$row;$field[]=$key;$placeholder[]=’:’.$key;

}//插入当前记录

$sql=”insert into {$this->tableName} (“.implode(‘, ‘, $field).’) values (‘.

implode(‘, ‘, $placeholder).’)’;$this->sqlQuery[‘params’]=$params;$this->sql=$sql;return $this->exec($sql,$this->sqlQuery[‘params’]);

}/**

* 删除记录

* @param string $where where条件

* @param array $params 绑定参数

* @return bool*/

public function delete($where = ”,$params = array())

{if($where!=”)$this->sqlQuery[‘where’]=$where;if($params!=”)$this->sqlQuery[‘params’]=$params;$sql=”delete from {$this->tableName} where {$this->sqlQuery[‘where’]}”;$this->sql=$sql;return $this->exec($sql,$this->sqlQuery[‘params’]);

}/**

* 简化的delete()方法,基于主键的删除*/

public function del($ids)

{$this->setField();$tmp=explode(‘,’, $ids);$tmp=array_map(function($item){return “‘”.$item.”‘”;

}, $tmp);$ids=implode(‘,’, $tmp);$sql=”delete from {$this->tableName} where {$this->fields[$this->tableName][‘pk’]}”.

” in ($ids)”;$this->sql=$sql;return $this->exec($sql);

}/**

* 得到插入的最后ID号*/

public functionlastId()

{return $this->pdo->lastInsertId();

}/**

* 修改数据 update 支持参数绑定 只支持where参数

* @param array $data 要改变的列的值数组 array(列名=>值)

* @param string $where where条件

* @param array $params 绑定参数

* @return boolean | int 受影响的行数*/

public function update($data,$where=”,$params= array())

{$this->setField();if(!is_array($data))return false;if($where!=”)$this->sqlQuery[‘where’]=$where;if($params!=”)$this->sqlQuery[‘params’]=$params;$updateField=array();foreach($data as $key=>$value)

{//不合法的字段不要

if(!in_array($key, $this->fields[$this->tableName]))continue;$updateField[]=”{$key}=:{$key}”;$this->sqlQuery[‘params’][“:{$key}”]=$value;

}$sql=”update {$this->tableName} set “.implode(‘,’, $updateField).” where {$this->sqlQuery[‘where’]}”;$this->sql=$sql;return $this->exec($sql,$this->sqlQuery[‘params’]);

}/**

* 得到数据表的所有字段信息*/

public functionsetField()

{if(is_array($this->fields[$this->tableName]))return;$sql=”desc {$this->tableName} “;$res=$this->findAll($sql);foreach ($res as $row)

{if($row[‘Key’]==’PRI’)$this->fields[$this->tableName][‘pk’]=$row[‘Field’];$this->fields[$this->tableName][]=$row[‘Field’];

}

}//得到当前操作表的字段信息

public functiongetField()

{if(!$this->fields[$this->tableName])$this->setField();return $this->fields[$this->tableName];

}//得到记录总数

public function count($sql=”)

{$this->sqlQuery[‘field’]=’count(*) as c’;$stmt=$this->query($sql);if(!$stmt)return false;$res=$stmt->fetch();//执行完之后要重置查询字段

return $res[‘c’];

}//得到sql执行错误

public functiongetError()

{return $this->error;

}public function setError($error)

{$this->error=$error;

}/**

* 扫行有结果集的查询,支持参数绑定

* 如果你需要遍历数据库,请使用query方法,然后foreach 返回的stmt对象便可。

* @param mixed $sql

* @return boolean|PDOStatement*/

public function query($sql=”)

{$sql=$this->joinSql($sql);$stmt=$this->pdo->prepare($sql);$errorInfo=$stmt->errorInfo();$stmt->setFetchMode(\PDO::FETCH_ASSOC);$stmt->execute($this->sqlQuery[‘params’]);//清除sql条件值,desc类部执行的sql语句,不用清楚缓存

if(strpos($sql,’desc’)!==0)$this->clearSqlQuery();$errorInfo=$stmt->errorInfo();if($errorInfo[0]!=’00000′)

{$this->setError($errorInfo[2]);return false;

}return $stmt;

}/**

* 执行没有结果集的查询,支持参数绑定

* @param string $sql

* @param array $params

* @return 返回受影响行数或false*/

public function exec($sql,$params = array())

{$stmt=$this->pdo->prepare($sql);if($params!=”)$this->sqlQuery[‘params’]=$params;$stmt->execute($this->sqlQuery[‘params’]);$this->clearSqlQuery();$errorInfo=$stmt->errorInfo();if($errorInfo[0]!=’00000′)

{$this->setError($errorInfo[2]);return false;

}return $stmt->rowCount();

}//设定绑定参数

public function params($params)

{$this->sqlQuery[‘params’]=empty($params)?”:$params;return $this;

}/**

* 自动绑定参数

* @param $params

* @return $this*/

public function autoParams($params)

{$this->setField();foreach ($params as $key => $row) {if(in_array($key, $this->fields[$this->tableName])) {$this->sqlQuery[‘params’][“:{$key}”] = $row;

}

}return $this;

}/**

* 组合sql语句

* @param mixed $sql

* @return 返回组合的sql语句*/

public function joinSql($sql)

{if(is_string($sql) && $sql!=”)

{$this->sql=$sql;return $sql;

}elseif(is_array($sql) && $sql!=”)

{foreach ($sql as $key=>$row)

{if(!array_key_exists($key, $this->sqlQuery))continue;$this->sqlQuery[$key]=$row;

}

}else{}$this->sql=”select {$this->sqlQuery[‘field’]} from {$this->tableName}\n”;if($this->sqlQuery[‘join’]!=”)$this->sql.=”{$this->sqlQuery[‘join’]} “;$this->sql.=”where {$this->sqlQuery[‘where’]}\n”;if($this->sqlQuery[‘group’]!=”)$this->sql.=”group by {$this->sqlQuery[‘group’]}\n”;if($this->sqlQuery[‘having’]!=”)$this->sql.=”having {$this->sqlQuery[‘having’]}\n”;if($this->sqlQuery[‘order’]!=”)$this->sql.=”order by {$this->sqlQuery[‘order’]}\n”;if($this->sqlQuery[‘limit’]!=”)$this->sql.=”limit {$this->sqlQuery[‘limit’]}\n”;if($this->sqlQuery[‘union’]!=”)$this->sql.=”union {$this->sqlQuery[‘union’]}\n”;return $this->sql;

}//设定字段的方法

public function field($field)

{$this->sqlQuery[‘field’]=empty($field)?’*’:$field;return $this;

}/**

*

* @param unknown_type $where

* @return \iphp\core\MyDb*/

public function where($where)

{$this->sqlQuery[‘where’]=empty($where)?’1′:$where;return $this;

}/**

* @param $tableName

* @param $condition

* @return $this*/

public function join($tableName,$condition)

{$this->sqlQuery[‘join’].=”join {$tableName} on {$condition}\n”;return $this;

}/**

* @param $tableName

* @param $condition

* @return $this*/

public function leftjoin($tableName,$condition)

{$this->sqlQuery[‘join’].=”left join {$tableName} on {$condition}\n”;return $this;

}/**

* @param $tableName

* @param $condition

* @return $this*/

public function rightjoin($tableName,$condition)

{$this->sqlQuery[‘join’].=”right join {$tableName} on {$condition}\n”;return $this;

}/**

* @param $group

* @return $this*/

public function group($group)

{$this->sqlQuery[‘group’]=empty($group)?”:$group;return $this;

}/**

* @param $having

* @return $this*/

public function having($having)

{$this->sqlQuery[‘having’]=empty($having)?”:$having;return $this;

}/**

* @param $order

* @return $this*/

public function order($order)

{$this->sqlQuery[‘order’]=empty($order)?”:$order;return $this;

}/**

* @param $limit

* @return $this*/

public function limit($limit)

{$this->sqlQuery[‘limit’]=empty($limit)?”:$limit;return $this;

}/**

* @param $union

* @return $this*/

public function union($union)

{$this->sqlQuery[‘union’]=empty($union)?”:$union;return $this;

}/**

* 清除sql缓存*/

public functionclearSqlQuery()

{//清除缓存前,先保存当前sql语句。

if(!empty($this->sqlQuery[‘params’]))

{foreach ($this->sqlQuery[‘params’] as $key=>$param)$this->sql=str_replace($key, ‘”‘.$param.'”‘, $this->sql);

}$this->sql=nl2br($this->sql);foreach ($this->sqlQuery as $key=>$row)

{if($key==’where’)$this->sqlQuery[$key]=’1′;elseif ($key==’field’)$this->sqlQuery[$key]=’*’;elseif ($key==’params’)$this->sqlQuery[$key]=array();else

$this->sqlQuery[$key]=”;

}

}//再执行findone findall方法之前,得到当前要执行的sql语句,

public functiongetSqlCache()

{$sql=$this->joinSql(”);if(!empty($this->sqlQuery[‘params’]))

{foreach ($this->sqlQuery[‘params’] as $key=>$param)$sql=str_replace($key, ‘”‘.$param.'”‘, $sql);

}return $sql;

}/**

* 得到当前数据库名称*/

public functiongetDbName()

{return $this->dbName;

}/**

* 得到用户名*/

public functiongetUser()

{return $this->username;

}/**

* 得到密码*/

public functiongetPass()

{return $this->password;

}public functiongetHost()

{return $this->host;

}public functiongetPort()

{return $this->port;

}/**

* 得到连接相关的详细信息。*/

public functiongetConnInfo()

{return array(‘host’=>$this->host,

‘port’=>$this->port,

‘username’=>$this->username,

‘password’=>$this->password,

‘dbname’=>$this->dbName,);

}/**

* 开启事务,并设置错误模式为异常

* 使用try cacth 来回滚或提交

* beginTransaction()方法将会关闭自动提交(autocommit)模式,

* 直到事务提交或者回滚以后才能恢复为pdo设置的模式*/

public functionbeginTransaction()

{$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);return $this->pdo->beginTransaction();

}/**

* 提交

* @return bool*/

public functioncommit()

{return $this->pdo->commit();

}/**

* 回滚事务

* @return bool*/

public functionrollBack()

{return $this->pdo->rollBack();

}/**

* 关闭连接*/

public functionclose()

{$this->pdo=null;

}/**

* 关闭所有连接*/

public static functioncloseAll()

{foreach(static::$_instance as $o)

{if($oinstanceof self)$o->close();

}

}/**

* 得到当前表的下一次自增长ID*/

public function getNextAutoIncrement($tableName)

{$sql=”show table status where name ='{$tableName}'”;$res=$this->findOne($sql);return $res[‘Auto_increment’];

}/**

* 为一个表增加一个TIMESTAMP字段

* @param $tableName 表名

* @param $name 字段名

* @return bool|int*/

public function addTIMESTAMP($tableName,$name=’utime’)

{$addSql=”alter table {$tableName} add {$name} TIMESTAMP

NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;”;$addSql.=”ALTER TABLE {$tableName} ADD index {$name}($name)”;return $this->exec($addSql);

}

}



版权声明:本文为weixin_34737066原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。