-
-
/**
- * 数据库pdo操作
- */
- class mysqlpdo {
- public static $pdostatement = null;
- /**
- * 数据库的连接参数配置
- * @var array
- * @access public
- */
- public static $config = array();
- /**
- * 是否使用永久连接
- * @var bool
- * @access public
- */
- public static $pconnect = false;
- /**
- * 错误信息
- * @var string
- * @access public
- */
- public static $error = '';
- /**
- * 单件模式,保存pdo类唯一实例,数据库的连接资源
- * @var object
- * @access public
- */
- protected static $link;
- /**
- * 是否已经连接数据库
- * @var bool
- * @access public
- */
- public static $connected = false;
- /**
- * 数据库版本
- * @var string
- * @access public
- */
- public static $dbversion = null;
- /**
- * 当前sql语句
- * @var string
- * @access public
- */
- public static $querystr = '';
- /**
- * 最后插入记录的id
- * @var integer
- * @access public
- */
- public static $lastinsertid = null;
- /**
- * 返回影响记录数
- * @var integer
- * @access public
- */
- public static $numrows = 0;
- // 事务指令数
- public static $transtimes = 0;
- /**
- * 构造函数,
- * @param $dbconfig 数据库连接相关信息,array('servername', 'username', 'password', 'defaultdb', 'db_port', 'db_type')
- */
- public function __construct($dbconfig=''){
- if (!class_exists('pdo')) self::throw_exception("不支持:pdo");
- //若没有传输任何参数,则使用默认的数据定义
- if (!is_array($dbconfig)) {
- $dbconfig = array(
- 'hostname' => db_host,
- 'username' => db_user,
- 'password' => db_pwd,
- 'database' => db_name,
- 'hostport' => db_port,
- 'dbms' => db_type,
- 'dsn' => db_type.":host=".db_host.";dbname=".db_name
- );
- }
- if(empty($dbconfig['hostname'])) self::throw_exception("没有定义数据库配置");
- self::$config = $dbconfig;
- if(empty(self::$config['params'])) self::$config['params'] = array();
- /*************************************华丽分隔线*******************************************/
- if (!isset(self::$link) ) {
- $configs = self::$config;
- if(self::$pconnect) {
- $configs['params'][constant('pdo::attr_persistent')] = true;
- }
- try {
- self::$link = new pdo( $configs['dsn'], $configs['username'], $configs['password'],$configs['params']);
- } catch (pdoexception $e) {
- self::throw_exception($e->getmessage());
- }
- if(!self::$link) {
- self::throw_exception('pdo connect error');
- return false;
- }
- self::$link->exec('set names '.db_charset);
- self::$dbversion = self::$link->getattribute(constant("pdo::attr_server_info"));
- // 标记连接成功
- self::$connected = true;
- // 注销数据库连接配置信息
- unset($configs);
- }
- return self::$link;
- }
- /**
- * 释放查询结果
- * @access function
- */
- static function free() {
- self::$pdostatement = null;
- }
- /************************/
- /* 数据库操作 */
- /************************/
- /**
- * 获得所有的查询数据
- * @access function
- * @return array
- */
- static function getall($sql=null) {
- if($sql != null)
- {
- self::query($sql);
- }
- //返回数据集
- $result = self::$pdostatement->fetchall(constant('pdo::fetch_assoc'));
- return $result;
- }
- /**
- * 获得一条查询结果
- * @access function
- * @param string $sql sql指令
- * @param integer $seek 指针位置
- * @return array
- */
- static function getrow($sql=null) {
- if($sql != null)
- {
- self::query($sql);
- }
- // 返回数组集
- $result = self::$pdostatement->fetch(constant('pdo::fetch_assoc'),constant('pdo::fetch_ori_next'));
- return $result;
- }
- /**
- * 执行sql语句,自动判断进行查询或者执行操作
- * @access function
- * @param string $sql sql指令
- * @return mixed
- */
- static function dosql($sql='') {
- if(self::ismainips($sql)) {
- return self::execute($sql);
- }else {
- return self::getall($sql);
- }
- }
- /**
- * 根据指定id查找表中记录(仅用于单表操作)
- * @access function
- * @param integer $priid 主键id
- * @param string $tables 数据表名
- * @param string $fields 字段名
- * @return arrayobject 表记录
- */
- static function findbyid($tabname,$priid,$fields='*'){
- $sql = 'select %s from %s where id=%d';
- return self::getrow(sprintf($sql, self::parsefields($fields), $tabname, $priid));
- }
- /**
- * 查找记录
- * @access function
- * @param string $tables 数据表名
- * @param mixed $where 查询条件
- * @param string $fields 字段名
- * @param string $order 排序
- * @param string $limit 取多少条数据
- * @param string $group 分组
- * @param string $having
- * @param boolean $lock 是否加锁
- * @return arrayobject
- */
- static function find($tables,$where="",$fields='*',$order=null,$limit=null,$group=null,$having=null) {
- $sql = 'select '.self::parsefields($fields)
- .' from '.$tables
- .self::parsewhere($where)
- .self::parsegroup($group)
- .self::parsehaving($having)
- .self::parseorder($order)
- .self::parselimit($limit);
- $dataall = self::getall($sql);
- if(count($dataall)==1){$rlt=$dataall[0];}else{$rlt=$dataall;}
- return $rlt;
- }
- /**
- * 插入(单条)记录
- * @access function
- * @param mixed $data 数据
- * @param string $table 数据表名
- * @return false | integer
- */
- function add($data,$table) {
- //过滤提交数据
- $data=self::filterpost($table,$data);
- foreach ($data as $key=>$val){
- if(is_array($val) && strtolower($val[0]) == 'exp') {
- $val = $val[1]; // 使用表达式 ???
- }elseif (is_scalar($val)){
- $val = self::fieldformat($val);
- }else{
- // 去掉复合对象
- continue;
- }
- $data[$key] = $val;
- }
- $fields = array_keys($data);
- array_walk($fields, array($this, 'addspecialchar'));
- $fieldsstr = implode(',', $fields);
- $values = array_values($data);
- $valuesstr = implode(',', $values);
- $sql = 'insert into '.$table.' ('.$fieldsstr.') values ('.$valuesstr.')';
- return self::execute($sql);
- }
- /**
- * 更新记录
- * @access function
- * @param mixed $sets 数据
- * @param string $table 数据表名
- * @param string $where 更新条件
- * @param string $limit
- * @param string $order
- * @return false | integer
- */
- static function update($sets,$table,$where,$limit=0,$order='') {
- $sets = self::filterpost($table,$sets);
- $sql = 'update '.$table.' set '.self::parsesets($sets).self::parsewhere($where).self::parseorder($order).self::parselimit($limit);
- return self::execute($sql);
- }
- /**
- * 保存某个字段的值
- * @access function
- * @param string $field 要保存的字段名
- * @param string $value 字段值
- * @param string $table 数据表
- * @param string $where 保存条件
- * @param boolean $asstring 字段值是否为字符串
- * @return void
- */
- static function setfield($field, $value, $table, $condition="", $asstring=false) {
- // 如果有'(' 视为 sql指令更新 否则 更新字段内容为纯字符串
- if(false === strpos($value,'(') || $asstring) $value = '"'.$value.'"';
- $sql = 'update '.$table.' set '.$field.'='.$value.self::parsewhere($condition);
- return self::execute($sql);
- }
- /**
- * 删除记录
- * @access function
- * @param mixed $where 为条件map、array或者string
- * @param string $table 数据表名
- * @param string $limit
- * @param string $order
- * @return false | integer
- */
- static function remove($where,$table,$limit='',$order='') {
- $sql = 'delete from '.$table.self::parsewhere($where).self::parseorder($order).self::parselimit($limit);
- return self::execute($sql);
- }
- /**
- +----------------------------------------------------------
- * 修改或保存数据(仅用于单表操作)
- * 有主键id则为修改,无主键id则为增加
- * 修改记录:
- +----------------------------------------------------------
- * @access function
- +----------------------------------------------------------
- * @param $tabname 表名
- * @param $apost 提交表单的 $_post
- * @param $priid 主键id
- * @param $anot 要排除的一个字段或数组
- * @param $acustom 自定义的一个数组,附加到数据库中保存
- * @param $isexits 是否已经存在 存在:true, 不存在:false
- +----------------------------------------------------------
- * @return boolean 修改或保存是否成功
- +----------------------------------------------------------
- */
- function saveorupdate($tabname, $apost, $priid="", $anot="", $acustom="", $isexits=false) {
- if(empty($tabname) || !is_array($apost) || is_int($anot)) return false;
- if(is_string($anot) && !empty($anot)) $anot = array($anot);
- if(is_array($anot) && is_int(key($anot))) $apost = array_diff_key($apost, array_flip($anot));
- if(is_array($acustom) && is_string(key($acustom))) $apost = array_merge($apost,$acustom);
- if (empty($priid) && !$isexits) { //新增
- $apost = array_filter($apost, array($this, 'removeempty'));
- return self::add($apost, $tabname);
- } else { //修改
- return self::update($apost, $tabname, "id=".$priid);
- }
- }
- /**
- * 获取最近一次查询的sql语句
- * @access function
- * @param
- * @return string 执行的sql
- */
- static function getlastsql() {
- $link = self::$link;
- if ( !$link ) return false;
- return self::$querystr;
- }
- /**
- * 获取最后插入的id
- * @access function
- * @param
- * @return integer 最后插入时的数据id
- */
- static function getlastinsid(){
- $link = self::$link;
- if ( !$link ) return false;
- return self::$lastinsertid;
- }
- /**
- * 获取db版本
- * @access function
- * @param
- * @return string
- */
- static function getdbversion(){
- $link = self::$link;
- if ( !$link ) return false;
- return self::$dbversion;
- }
- /**
- * 取得数据库的表信息
- * @access function
- * @return array
- */
- static function gettables() {
- $info = array();
- if(self::query("show tables")) {
- $result = self::getall();
- foreach ($result as $key => $val) {
- $info[$key] = current($val);
- }
- }
- return $info;
- }
- /**
- * 取得数据表的字段信息
- * @access function
- * @return array
- */
- static function getfields($tablename) {
- // 获取数据库联接
- $link = self::$link;
- $sql = "select
- ordinal_position ,column_name, column_type, data_type,
- if(isnull(character_maximum_length), (numeric_precision + numeric_scale), character_maximum_length) as maxchar,
- is_nullable, column_default, column_key, extra, column_comment
- from
- information_schema.columns
- where
- table_name = :tabname and table_schema='".db_name."'";
- self::$querystr = sprintf($sql, $tablename);
- $sth = $link->prepare($sql);
- $sth->bindparam(':tabname', $tablename);
- $sth->execute();
- $result = $sth->fetchall(constant('pdo::fetch_assoc'));
- $info = array();
- foreach ($result as $key => $val) {
- $info[$val['column_name']] = array(
- 'postion' => $val['ordinal_position'],
- 'name' => $val['column_name'],
- 'type' => $val['column_type'],
- 'd_type' => $val['data_type'],
- 'length' => $val['maxchar'],
- 'notnull' => (strtolower($val['is_nullable']) == "no"),
- 'default' => $val['column_default'],
- 'primary' => (strtolower($val['column_key']) == 'pri'),
- 'autoinc' => (strtolower($val['extra']) == 'auto_increment'),
- 'comment' => $val['column_comment']
- );
- }
- // 有错误则抛出异常
- self::haveerrorthrowexception();
- return $info;
- }
- /**
- * 关闭数据库
- * @access function
- */
- static function close() {
- self::$link = null;
- }
- /**
- * sql指令安全过滤
- * @access function
- * @param string $str sql指令
- * @return string
- */
- static function escape_string($str) {
- return addslashes($str);
- }
- /************************/
- /* 内部操作方法 */
- /************************/
- /**
- * 有出错抛出异常
- * @access function
- * @return
- */
- static function haveerrorthrowexception() {
- $obj = empty(self::$pdostatement) ? self::$link : self::$pdostatement;
- $arrerror = $obj->errorinfo();
- if($arrerror[0] !== '00000') { // 有错误信息
- self::$error = $arrerror[0]."|".$arrerror[2]. "
[ sql ] : ".self::$querystr." ";
- self::throw_exception(self::$error);
- return false;
- }
- //主要针对execute()方法抛出异常
- if(self::$querystr=='')self::throw_exception('query was empty
[ sql语句 ] :');
- }
- /**
- * where分析
- * @access function
- * @param mixed $where 查询条件
- * @return string
- */
- static function parsewhere($where) {
- $wherestr = '';
- if(is_string($where) || is_null($where)) {
- $wherestr = $where;
- }
- return empty($wherestr)?'':' where '.$wherestr;
- }
- /**
- * order分析
- * @access function
- * @param mixed $order 排序
- * @return string
- */
- static function parseorder($order) {
- $orderstr = '';
- if(is_array($order))
- $orderstr .= ' order by '.implode(',', $order);
- else if(is_string($order) && !empty($order))
- $orderstr .= ' order by '.$order;
- return $orderstr;
- }
- /**
- * limit分析
- * @access function
- * @param string $limit
- * @return string
- */
- static function parselimit($limit) {
- $limitstr = '';
- if(is_array($limit)) {
- if(count($limit)>1)
- $limitstr .= ' limit '.$limit[0].' , '.$limit[1].' ';
- else
- $limitstr .= ' limit '.$limit[0].' ';
- } else if(is_string($limit) && !empty($limit)) {
- $limitstr .= ' limit '.$limit.' ';
- }
- return $limitstr;
- }
- /**
- * group分析
- * @access function
- * @param mixed $group
- * @return string
- */
- static function parsegroup($group) {
- $groupstr = '';
- if(is_array($group))
- $groupstr .= ' group by '.implode(',', $group);
- else if(is_string($group) && !empty($group))
- $groupstr .= ' group by '.$group;
- return empty($groupstr)?'':$groupstr;
- }
- /**
- * having分析
- * @access function
- * @param string $having
- * @return string
- */
- static function parsehaving($having) {
- $havingstr = '';
- if(is_string($having) && !empty($having))
- $havingstr .= ' having '.$having;
- return $havingstr;
- }
- /**
- * fields分析
- * @access function
- * @param mixed $fields
- * @return string
- */
- function parsefields($fields) {
- if(is_array($fields)) {
- array_walk($fields, array($this, 'addspecialchar'));
- $fieldsstr = implode(',', $fields);
- }else if(is_string($fields) && !empty($fields)) {
- if( false === strpos($fields,'`') ) {
- $fields = explode(',',$fields);
- array_walk($fields, array($this, 'addspecialchar'));
- $fieldsstr = implode(',', $fields);
- }else {
- $fieldsstr = $fields;
- }
- }else $fieldsstr = '*';
- return $fieldsstr;
- }
- /**
- * sets分析,在更新数据时调用
- * @access function
- * @param mixed $values
- * @return string
- */
- private function parsesets($sets) {
- $setsstr = '';
- if(is_array($sets)){
- foreach ($sets as $key=>$val){
- $key = self::addspecialchar($key);
- $val = self::fieldformat($val);
- $setsstr .= "$key = ".$val.",";
- }
- $setsstr = substr($setsstr,0,-1);
- }else if(is_string($sets)) {
- $setsstr = $sets;
- }
- return $setsstr;
- }
- /**
- * 字段格式化
- * @access function
- * @param mixed $value
- * @return mixed
- */
- static function fieldformat(&$value) {
- if(is_int($value)) {
- $value = intval($value);
- } else if(is_float($value)) {
- $value = floatval($value);
- } elseif(preg_match('/^\(\w*(\+|\-|\*|\/)?\w*\)$/i',$value)){
- // 支持在字段的值里面直接使用其它字段
- // 例如 (score+1) (name) 必须包含括号
- $value = $value;
- }else if(is_string($value)) {
- $value = '\''.self::escape_string($value).'\'';
- }
- return $value;
- }
- /**
- * 字段和表名添加` 符合
- * 保证指令中使用关键字不出错 针对mysql
- * @access function
- * @param mixed $value
- * @return mixed
- */
- static function addspecialchar(&$value) {
- if( '*' == $value || false !== strpos($value,'(') || false !== strpos($value,'.') || false !== strpos($value,'`')) {
- //如果包含* 或者 使用了sql方法 则不作处理
- } elseif(false === strpos($value,'`') ) {
- $value = '`'.trim($value).'`';
- }
- return $value;
- }
- /**
- +----------------------------------------------------------
- * 去掉空元素
- +----------------------------------------------------------
- * @access function
- +----------------------------------------------------------
- * @param mixed $value
- +----------------------------------------------------------
- * @return mixed
- +----------------------------------------------------------
- */
- static function removeempty($value){
- return !empty($value);
- }
- /**
- * 执行查询 主要针对 select, show 等指令
- * @access function
- * @param string $sql sql指令
- * @return mixed
- */
- static function query($sql='') {
- // 获取数据库联接
- $link = self::$link;
- if ( !$link ) return false;
- self::$querystr = $sql;
- //释放前次的查询结果
- if ( !empty(self::$pdostatement) ) self::free();
- self::$pdostatement = $link->prepare(self::$querystr);
- $bol = self::$pdostatement->execute();
- // 有错误则抛出异常
- self::haveerrorthrowexception();
- return $bol;
- }
- /**
- * 数据库操作方法
- * @access function
- * @param string $sql 执行语句
- * @param boolean $lock 是否锁定(默认不锁定)
- * @return void
- public function execute($sql='',$lock=false) {
- if(empty($sql)) $sql = $this->querystr;
- return $this->_execute($sql);
- }*/
- /**
- * 执行语句 针对 insert, update 以及delete
- * @access function
- * @param string $sql sql指令
- * @return integer
- */
- static function execute($sql='') {
- // 获取数据库联接
- $link = self::$link;
- if ( !$link ) return false;
- self::$querystr = $sql;
- //释放前次的查询结果
- if ( !empty(self::$pdostatement) ) self::free();
- $result = $link->exec(self::$querystr);
- // 有错误则抛出异常
- self::haveerrorthrowexception();
- if ( false === $result) {
- return false;
- } else {
- self::$numrows = $result;
- self::$lastinsertid = $link->lastinsertid();
- return self::$numrows;
- }
- }
- /**
- * 是否为数据库更改操作
- * @access private
- * @param string $query sql指令
- * @return boolen 如果是查询操作返回false
- */
- static function ismainips($query) {
- $queryips = 'insert|update|delete|replace|create|drop|load data|select .* into|copy|alter|grant|revoke|lock|unlock';
- if (preg_match('/^\s*"?(' . $queryips . ')\s+/i', $query)) {
- return true;
- }
- return false;
- }
- /**
- * 过滤post提交数据
- * @access private
- * @param mixed $data post提交数据
- * @param string $table 数据表名
- * @return mixed $newdata
- */
- static function filterpost($table,$data) {
- $table_column = self::getfields($table);
- $newdata=array();
- foreach ($table_column as $key=>$val){
- if(array_key_exists($key,$data) && ($data[$key])!==''){
- $newdata[$key] = $data[$key];
- }
- }
- return $newdata;
- }
- /**
- * 启动事务
- * @access function
- * @return void
- */
- static function starttrans() {
- //数据rollback 支持
- $link = self::$link;
- if ( !$link ) return false;
- if (self::$transtimes == 0) {
- $link->begintransaction();
- }
- self::$transtimes++;
- return ;
- }
- /**
- * 用于非自动提交状态下面的查询提交
- * @access function
- * @return boolen
- */
- static function commit() {
- $link = self::$link;
- if ( !$link ) return false;
- if (self::$transtimes > 0) {
- $result = $link->commit();
- self::$transtimes = 0;
- if(!$result){
- self::throw_exception(self::$error());
- return false;
- }
- }
- return true;
- }
- /**
- * 事务回滚
- * @access function
- * @return boolen
- */
- public function rollback() {
- $link = self::$link;
- if ( !$link ) return false;
- if (self::$transtimes > 0) {
- $result = $link->rollback();
- self::$transtimes = 0;
- if(!$result){
- self::throw_exception(self::$error());
- return false;
- }
- }
- return true;
- }
/**
- * 错误处理
- * @access function
- * @return void
- */
- static function throw_exception($err){
- echo '
ERROR:'.$err.' ';
- }
- }
-
复制代码
|