php pdo mysql数据库操作类
<?php
namespace iphp\core;
use iphp\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 class MyDb
{
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 function getPdo()
{
return $this->pdo;
}
/**
* 得到当前sql语句,并完成参数替换
* @return string
*/
public function getSql()
{
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 function lastId()
{
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 function setField()
{
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 function getField()
{
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 function getError()
{
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 function clearSqlQuery()
{
//清除缓存前,先保存当前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 function getSqlCache()
{
$sql=$this->joinSql('');
if(!empty($this->sqlQuery['params']))
{
foreach ($this->sqlQuery['params'] as $key=>$param)
$sql=str_replace($key, '"'.$param.'"', $sql);
}
return $sql;
} /**
* 得到当前数据库名称
*/
public function getDbName()
{
return $this->dbName;
} /**
* 得到用户名
*/
public function getUser()
{
return $this->username;
} /**
* 得到密码
*/
public function getPass()
{
return $this->password;
} public function getHost()
{
return $this->host;
} public function getPort()
{
return $this->port;
} /**
* 得到连接相关的详细信息。
*/
public function getConnInfo()
{
return array(
'host'=>$this->host,
'port'=>$this->port,
'username'=>$this->username,
'password'=>$this->password,
'dbname'=>$this->dbName,
);
} /**
* 开启事务,并设置错误模式为异常
* 使用try cacth 来回滚或提交
* beginTransaction()方法将会关闭自动提交(autocommit)模式,
* 直到事务提交或者回滚以后才能恢复为pdo设置的模式
*/
public function beginTransaction()
{
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
return $this->pdo->beginTransaction();
} /**
* 提交
* @return bool
*/
public function commit()
{
return $this->pdo->commit();
} /**
* 回滚事务
* @return bool
*/
public function rollBack()
{
return $this->pdo->rollBack();
} /**
* 关闭连接
*/
public function close()
{
$this->pdo=null;
} /**
* 关闭所有连接
*/
public static function closeAll()
{
foreach(static::$_instance as $o)
{
if($o instanceof 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);
}
}
php pdo mysql数据库操作类的更多相关文章
- php : mysql数据库操作类演示
设计目标: 1,该类一实例化,就可以自动连接上mysql数据库: 2,该类可以单独去设定要使用的连接编码(set names XXX) 3,该类可以单独去设定要使用的数据库(use XXX): 4,可 ...
- php MySQL数据库操作类源代码
php MySQL数据库操作类源代码: <?php class MySQL{ private $host; //服务器地址 private $name; //登录账号 private $pwd; ...
- 设计模式 - 单例模式mysql数据库操作类
待续... index.php 调用方法: <?php header('Content-Type:text/html; charset=utf8'); require 'instance.php ...
- 一个基于PDO的数据库操作类(新) 一个PDO事务实例
<?php /* * 作者:胡睿 * 日期:2011/03/19 * 电邮:hooray0905@foxmail.com * * 20110319 * 常用数据库操作,如:增删改查,获取单条记录 ...
- MySQL数据库操作类(PHP实现,支持连贯操作)
<?php /** * Author: suvan * CreateTime: 2018/2/27 * description: 数据库操作类(仅对接MySQL数据库,主要利用MySQLi函数) ...
- PHP 基于pdo的数据库操作类
http://www.php.cn/php-weizijiaocheng-404645.html <?php class Pdodb{ protected $pdo; protected ...
- php 封装mysql 数据库操作类
<?phpheader('content-type:text/html;charset=utf-8');//封装mysql 连接数据库php_mysql//封装mysql 连接数据库ph ...
- C# MySQL 数据库操作类
using System; using System.Configuration; using System.Collections; using System.Data; using MySql.D ...
- DELPHI XE MYSQL数据库操作类 MYSQLHELPER
注: 无需odbc配置 {* * MySQL Helper v1.0 * 2015.6.19 * 说明: * 这是一个操作MySQL的类,该类必须和libmysql.dll,dbxmys.dll两个文 ...
随机推荐
- 多线程程序中fork导致的一些问题
最近项目中,在使用多线程和多进程时,遇到了些问题. 问题描述:在多线程程序中fork出一个新进程,发现新的进程无法正常工作. 解决办法:将开线程的代码放在fork以后.也就是放在新的子进程中进行创建. ...
- 区段extent及数据块
一.区段是表空间中由某个段所使用的一块磁盘空间.他是一组连续的oracle数据块.引入extent的目的是为了减少磁盘空间分配的次数,如果是采用oracle数据块直接分配的话就增加了oracle磁盘空 ...
- asp.net实现伪静态遇到的问题
之前在一次项目(asp.net网站)中要用到伪静态技术,实现的思路大致是这样的: 在全局配置文件Global.asax(普通的类可以通过实现IHttpModule来完成)中的Application_B ...
- linux操作系统下的码农常用工具
IDE: Pycharm PHPStorm Zend Studio 文本编辑器: VIM Sublime Text 版本管理: svn RapidSVN git git ui 文件对比: Meld D ...
- Elevator(hdoj 1008)
Problem Description The highest building in our city has only one elevator. A request list is made u ...
- Oracle EBS-SQL (INV-10):检查库存接口.sql
/*检查库存接口表*/ select msi.segment1 项目编码, msi.description ...
- CentOS7 yum lamp 虚拟主机配置 lamp各组件简单影响性能的参数调整--for 一定的环境需求
LAMP Server on CentOS 7 Updated Tuesday, January 13, 2015 by Joel Kruger This guide provides step-by ...
- 我使用过的Linux命令之file - 检测并显示文件类型
摘自:http://codingstandards.iteye.com/blog/804463 我使用过的Linux命令之file - 检测并显示文件类型 用途说明 file命令是用来检测并显示文件类 ...
- 彩虹vpn免费10分钟
账号:rainbowvpn password:10fenzhong server地址:t.chqvpn.com l2tp密钥:123456
- GDAL1.11版本号对SHP文件索引加速測试
GDAL库中对于矢量数据的读取中能够设置一些过滤器来对矢量图形进行筛选.对于Shapefile格式来说.假设数据量太大,设置这个过滤器时间慢的简直无法忍受.好在GDAL1.10版本号開始支持读取Sha ...