"='?0'", 'neq' => "<>'?0'", 'eqi' => '=?0', 'neqi' => '<>?0', 'lt' => "<'?0'", 'elt' => "<='?0'", 'gt' => ">'?0'", 'egt' => ">='?0'", 'lti' => ' '<=?0', 'gti' => '>?0', 'egti' => '>=?0', 'like' => "LIKE '%?0%'", 'notlike' => "NOT LIKE '%?0%'", 'leftlike' => "LIKE '%?0'", 'rightlike' => "LIKE '?0%'", 'in' => "IN(?0)", 'notin' => "NOT IN(?0)", 'between' => "BETWEEN '?0' AND '?1'", 'notbetween' => "NOT BETWEEN '?0' AND '?1'", 'betweeni' => "BETWEEN ?0 AND ?1", 'notbetweeni' => "NOT BETWEEN ?0 AND ?1" ); //sql中禁用方法 protected $disabledfua = array('dumpfile','outfile','load_file','system_user'); public function __construct() { $this->rock = $GLOBALS['rock']; $this->errorbool = false; $this->errormsg = ''; if(getconfig('dbencrypt')){ $this->db_host = $this->rock->jm->uncrypt(DB_HOST); $this->db_user = $this->rock->jm->uncrypt(DB_USER); $this->db_pass = $this->rock->jm->uncrypt(DB_PASS); $this->db_base = $this->rock->jm->uncrypt(DB_BASE); }else{ $this->db_host = DB_HOST; $this->db_user = DB_USER; $this->db_pass = DB_PASS; $this->db_base = DB_BASE; } $this->basename = $this->db_base; } public function __destruct() { if($this->conn){ $this->tranend(); $this->close(); } //记录访问sql日志 if(getconfig('sqllog')){ $sql = ''; $filstr = 'sqllog_'.date('Y.m.d.H.i.s').'_'.$this->rock->adminid.'_'.str_shuffle('abcdefghijklmn').'.log'; foreach($this->sqlarr as $sql1)$sql.="\n\n$sql1;"; if($sql!='')$this->rock->createtxt(''.UPDIR.'/sqllog/'.date('Y-m-d').'/'.$filstr.'', "时间[".$this->rock->now."],用户[".$this->rock->adminid.".".$this->rock->adminname."],IP[".$this->rock->ip."],WEB[".$this->rock->web."],URL[".$this->rock->nowurl()."]".$sql); } } protected function connect(){} protected function selectdb($name) { $this->basename = $name; } protected function querysql($sql){return false;} protected function starttran(){} protected function endtran($bo){} public function fetch_array($res, $type=0){return false;} public function insert_id(){return 0;} public function error(){return '';} public function close(){} public function changeattr($host, $user, $pass, $base) { $this->db_host = $host; $this->db_user = $user; $this->db_pass = $pass; $this->db_base = $base; } public function connectdb() { $this->errormsg = ''; $this->connect(); return $this->conn; } public function query($sql, $ebo=true) { if($this->conn == null)$this->connect(); if($this->conn == null)exit('数据库的帐号/密码有错误!'.$this->errormsg.''); $sql = trim($sql); $sql = str_replace(array('[Q]','[q]','{asqom}'), array($this->perfix, $this->perfix,''), $sql); $sqls = strtolower($sql); foreach($this->disabledfua as $fus)if(contain($sqls,$fus))exit('禁止包含'.$fus.'字符串'); $this->countsql++; $this->sqlarr[] = $sql; $this->nowsql = $sql; $this->count = 0; try { $rsbool = $this->querysql($sql); } catch (Exception $e) { $rsbool = false; $this->errormsg = $e->getMessage(); } $this->nowerror = false; if(!$rsbool)$this->nowerror = true; $stabs = ''.$this->perfix.'log'; if(!contain($sql, $stabs) && !$rsbool)$this->errorlast = $this->error(); //最后错误信息 //记录错误sql if(!$rsbool && $ebo){ $txt = '[ERROR SQL]'.chr(10).''.$sql.''.chr(10).''.chr(10).'[Reason]'.chr(10).''.$this->error().''.chr(10).''; $efile = $this->rock->debug($txt,''.DB_DRIVE.'_sqlerr', true); $errmsg = str_replace("'",''', $this->error()); if(!contain($sql, $stabs)){ m('log')->addlogs('错误SQL',''.$errmsg.'', 2, array( 'url' => $efile )); } } return $rsbool; } /** * 返回最后错误信息 */ public function lasterror() { $err = $this->errorlast; if($err=='')$err = $this->error(); return $err; } public function execsql($sql) { $rsa = $this->query($sql); $this->iudarr[]=$rsa; return $rsa; } public function getLastSql() { return $this->nowsql; } public function getsyscount($lx='') { $to = 0; if($lx=='')return $to; $lx = strtoupper($lx); $rsa = $this->getall('SELECT '.$lx.'() as total'); $to = $rsa[0]['total']; return $to; } /** * 返回使用SQL_CALC_FOUND_ROWS,统计总记录数 */ public function found_rows() { return $this->getsyscount('found_rows'); } /** * 返回update,insert,delete上所影响的条数 */ public function row_count() { return $this->getsyscount('row_count'); } /** * 获取select的sql */ public function getsql($arr=array()) { $where = $table = $order = $limit = $group = ''; $fields = '*'; if(isset($arr['table']))$table=$arr['table']; if(isset($arr['where']))$where=$arr['where']; if(isset($arr['order']))$order=$arr['order']; if(isset($arr['limit']))$limit=$arr['limit']; if(isset($arr['group']))$group=$arr['group']; if(isset($arr['fields']))$fields=$arr['fields']; $where = $this->getwhere($where); $table = $this->gettable($table); $sql = "SELECT $fields FROM $table"; if($where!=''){ //$where = $this->filterstr($where); $sql.=" WHERE $where"; } if($order!='')$sql.=" ORDER BY $order"; if($group!='')$sql.=" GROUP BY $group"; if($limit!='')$sql.=" LIMIT $limit"; return $sql; } //弃用过滤 public function filterstr($str) { $str = strtolower($str); $file= explode(',','delete,drop,update,union,exec,insert,declare,master,truncate,create,alter,database'); $res = array(); foreach($file as $fid)$res[]=''; $str = str_replace($file, $res, $str); return $str; } public function getone($table,$where,$fields='*',$order='') { $rows = $this->getrows($table,$where,$fields,$order,'1'); $row = false; if($this->count>0)$row=$rows[0]; return $row; } public function getrows($table,$where,$fields='*',$order='', $limit='',$group='') { $sql = $this->getsql(array( 'table' => $table, 'where' => $where, 'fields'=> $fields, 'order' => $order, 'limit' => $limit, 'group' => $group )); return $this->getall($sql); } public function getall($sql) { $res=$this->query($sql); $arr=array(); if($res){ while($row=$this->fetch_array($res)){ $arr[] = $row; $this->count++; } } return $arr; } /** string table1 a left JOIN table2 b on b.uid=a.id array(table=>$table,join=>'left') */ public function gettable($arr) { if(is_array($arr)){ $s = '';$oi=0; foreach($arr as $k=>$v){ if($oi==0){ $s=''.$v.' a'; }else{ if($k=='join')$s.=' '.$v.' JOIN'; if($k=='table1')$s.=' '.$v.' b'; if($k=='where')$s.=' ON '.$v.''; if($k=='where1')$s.=' AND '.$v.''; } $oi++; } $arr = $s; } return $arr; } /** 条件的 $arrs = array( 'id|eqi|a' => '0', 'name|like' => '我', 'id|notin' => '0,12', 'enddt|rightlike' => '2015-10', 'startdt|between' => '2015-10-01@@@2015-10-31', 'price|notbetweeni' => '1@@@10', 'sid > ?0 and '0@@@2' ); */ public function getwhere($where='') { $len = func_num_args(); $arr = array(); $sfh1 = ''; for($i=0; $i<$len; $i++){ $sfh = func_get_arg($i); if(is_numeric($sfh)){ $arr[] = "`id`='$sfh'"; }else if($sfh=='AND' || $sfh=='OR' || $sfh=='and' || $sfh=='or'){ $sfh1 = $sfh; }else{ $arr[] = $this->_getwhere($sfh); } } $joins = ') AND ('; if($sfh1!='')$joins = ') '.$sfh1.' ('; $where = join($joins, $arr); if($sfh1!='')$where = "($where)"; return $where; } private function _getwhere($where='') { if($where=='')return ''; if(is_numeric($where)){ $where = "`id`='$where'"; }else if(is_array($where)){ $sarr = array(); foreach($where as $fid=>$val){ $qz = ''; $farr = explode('|', $fid); $fid = $farr[0]; $_fhs = "='?0'"; if(isset($farr[1])){ $_fh = $farr[1]; if(isset($this->exparray[$_fh]))$_fhs=$this->exparray[$_fh]; } if(isset($farr[2]))$qz=''.$farr[2].'.'; $vala = explode('@@@', $val); $val1 = $vala[0];$val2=''; if(isset($vala[1]))$val2=$vala[1]; $_bo1 = $this->contain($fid,'?0'); if($_bo1)$_fhs = $fid; $_fhs = str_replace(array('?0','?1'), array($val1,$val2), $_fhs); $s = $_fhs; if(!$_bo1)$s = ''.$qz.'`'.$fid.'` '.$_fhs.''; $sarr[]=$s; } $where = join(' AND ', $sarr); } return $where; } /** * 以$kfied作为主键返回数组 */ public function getarr($table, $where='', $fields='*', $kfied='id') { $sql = $this->getsql(array( 'table' => $table, 'where' => $where, 'fields'=> "`$kfied`,$fields" )); $res = $this->query($sql); $arr = array(); if($res){ while($row=$this->fetch_array($res)){ $arr[$row[$kfied]] = $row; $this->count++; } } return $arr; } /** 读取全部同时将第一个字段作为主键(读取的数据存在数组里) */ public function getkeyall($table,$fields,$where='') { $sql = $this->getsql(array( 'table' => $table, 'where' => $where, 'fields'=> $fields )); $res=$this->query($sql); $arr=array(); if($res){ while(list($ka,$ab) = $this->fetch_array($res, 1)){ $arr[$ka]=$ab; $this->count++; } } return $arr; } /** 读取一条sql语句用规定字符连接起来 */ public function getjoinval($table,$fields,$where='',$join=',') { $sql = $this->getsql(array( 'table' => $table, 'where' => $where, 'fields'=> $fields )); $res=$this->query($sql); $arr=array(); if($res){ while(list($kv) = $this->fetch_array($res, 1)){ $arr[]=$kv; $this->count++; } } return join($join,$arr); } /** 读取某行某字段的 */ public function getmou($table,$fields,$where,$order='') { $sql = $this->getsql(array( 'table' => $table, 'where' => $where, 'fields'=> $fields, 'order' => $order )); $res=$this->query($sql); if($res){ $row = $this->fetch_array($res, 1); if($row){ $this->count = 1; return $row[0]; } } return false; } /** * 开启事务 */ public function routinestart() { $this->starttran(); } /** * 提交/回滚事务 * $bo=null 自动 true 提交,false 回滚 */ public function routineend($bo=null) { if(!is_bool($bo))$bo = $this->backsql(); $this->endtran($bo); return $bo; } /** * 启用事务,没有事务 */ private function tranbegin($sql) { //if($this->errorbool)return false; if($this->conn == null)$this->connect(); $this->iudcount++; if(!$this->tran){ //$this->starttran(); //$this->tran=true; } $rsa = $this->query($sql); $this->iudarr[]=$rsa; if(!$rsa)$this->errorbool = true; return $rsa; } /** 事务结束 */ private function tranend() { if($this->tran){ //$this->endtran($this->backsql()); } $this->tran=false; } /** 判断插入更新删除sql语句是否有错 */ public function backsql() { $subt=true; foreach($this->iudarr as $tra){ if(!$tra){ $subt=false; break; } } return $subt; } public function insert($table,$name,$values,$sel=false) { $sql="insert into ".$this->gettables($table)." ($name) "; if(!$sel){ $sql.="values($values)"; }else{ $sql.=$values; } return $this->tranbegin($sql); } public function update($table,$content,$where) { $where = $this->getwhere($where); $sql="update ".$this->gettables($table)." set $content where $where "; return $this->tranbegin($sql); } public function delete($table,$where) { $where = $this->getwhere($where); $sql="delete from ".$this->gettables($table)." where $where "; return $this->tranbegin($sql); } /** 记录添加修改 */ public function record($table,$array,$where='') { $addbool = true; if(!$this->isempt($where))$addbool=false; $cont = ''; if(is_array($array)){ foreach($array as $key=>$val){ $cont.=",`$key`=".$this->toaddval($val).""; } $cont = substr($cont,1); }else{ $cont = $array; } $table = $this->gettables($table); if($addbool){ $sql="insert into $table set $cont"; }else{ $where = $this->getwhere($where); $sql="update $table set $cont where $where"; } return $this->tranbegin($sql); } /** * 处理表名 */ public function gettables($str) { if(!contain($str,'`'))$str='`'.$str.'`'; return $str; } /** 返回总条数 */ public function rows($table,$where,$rowtype='count(1)'){ return (int)$this->getmou($table,$rowtype,$where); } /** 返回所有数据库的表 */ public function getalltable($base='') { if($base=='')$base = $this->basename; $sql = "select `TABLE_NAME` from information_schema.`TABLES` where `TABLE_SCHEMA`='$base'"; $arr = $this->getall($sql); $rows= array(); foreach($arr as $k=>$rs)$rows[] = $rs['TABLE_NAME']; return $rows; } /** 返回表所有字段 */ public function getallfields($table) { $finfo = $this->gettablefields($table); foreach ($finfo as $val) { $arr[] = $val['name']; } return $arr; } public function getfields($table) { $f = $this->getallfields($table); foreach($f as $f1)$arr[$f1]=''; return $arr; } public function gettablefields($table, $base='',$whe='') { if($base=='')$base = $this->db_base; $sql = "select COLUMN_NAME as `name`,DATA_TYPE as `type`,COLUMN_COMMENT as `explain`,COLUMN_TYPE as `types`,`COLUMN_DEFAULT` as dev,`IS_NULLABLE` as isnull,`CHARACTER_MAXIMUM_LENGTH` as lens,`NUMERIC_PRECISION` as xslen1,`NUMERIC_SCALE` as xslen2 from information_schema.COLUMNS where `TABLE_NAME`='$table' and `TABLE_SCHEMA` ='$base' $whe order by `ORDINAL_POSITION`"; return $this->getall($sql); } /** 读取表结构 */ public function gettablecolumn($table, $fields='') { $where = ''; if($fields!='')$where = "and `COLUMN_NAME`='$fields'"; $sql = "select COLUMN_NAME as `name`,DATA_TYPE as `type`,COLUMN_COMMENT as `explain`,COLUMN_TYPE as `types`,COLUMN_DEFAULT as 'defval' from information_schema.COLUMNS where `TABLE_NAME`='$table' and `TABLE_SCHEMA` ='$this->db_base' $where order by `ORDINAL_POSITION`"; $arr = $this->getall($sql); $rows = array(); foreach($arr as $k=>$rs){ $dev = 'NULL'; if(!$this->isempt($rs['defval']))$dev=$rs['defval']; $str = "`".$rs['name']."` ".$rs['types']." DEFAULT ".$dev.""; if(!$this->isempt($rs['explain']))$str.=" COMMENT '".$rs['explain']."'"; $rows[] = $str; } return $rows; } public function showcreatetable($table) { $sql = "show create table `$table`"; $res= $this->query($sql); list($ka,$nr) = $this->fetch_array($res, 1); return $nr; } /** 判断变量是否为空 */ public function isempt($str) { return isempt($str); } public function contain($str,$a) { $bool=false; if(!$this->isempt($a) && !$this->isempt($str)){ $ad=strpos($str,$a); if($ad>0||!is_bool($ad))$bool=true; } return $bool; } /** 转换数据库可插入的对象 */ public function toaddval($str) { $adstr="'$str'"; if($this->isempt($str)){ $adstr='null'; }else{ if(substr($str,0,4)=='(&;)')$adstr=substr($str,4); } return $adstr; } /** * 替换特殊符合' */ public function tocovexec($str, $lx=0) { $str = str_replace('\'', ''',$str); if($lx==1){ $str = str_replace("\n", '',$str); } return $str; } /** 创建随机编号 */ public function ranknum($table,$field='num',$n=6, $dx=0) { $arr = array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'); $num = ''; for($i=1;$i<=$n;$i++)$num.=$arr[rand(0,count($arr)-1)]; if($dx==1)$num = strtoupper($num);//转换成大写 $rsnum = $this->getmou($table,$field,"`$field`='$num'"); return ($rsnum)?$this->ranknum($table,$field,$n, $dx):$num; } /** 流水编号 */ public function sericnum($num, $table,$fields='sericnum', $ws=4, $whe='') { $dts = explode('-', date('Y-m-d')); $ymd = $dts[0].$dts[1].$dts[2]; $ym = $dts[0].$dts[1]; $num = str_replace('Ymd', $ymd, $num); $num = str_replace('Ym', $ym, $num); $num = str_replace('Year', $dts[0], $num); $num = str_replace('Day', $dts[2], $num); $num = str_replace('Month', $dts[1], $num); $where = "`$fields` like '".$num."%' $whe"; $max = (int)$this->getmou($table, "max(cast(replace(`$fields`,'$num','') as decimal(10)))", $where); $max++; $wsnum = ''.$max.''; $len = strlen($wsnum); $oix = $ws - $len; for($i=1;$i<=$oix;$i++)$wsnum='0'.$wsnum; $num .= $wsnum; return $num; } /** * 获取所有顶级信息连接起来 * @param $table 表名 * @param $pfields 上级字段 $jfield 要连接的字段名 $afid = 值 */ private $joinarr=array(); private $joinlen; public function getpval($table,$pfields,$jfield,$afid,$plit='/',$afield='id',$maxlen=8) { $this->joinarr = array(); $this->joinlen = 0; $this->getpvala($table,$pfields,$jfield,$afid,$afield,$maxlen); return join($plit,array_reverse($this->joinarr)); } private function getpvala($table,$pfields,$jfield,$afid,$afield,$maxlen) { if(count($this->joinarr)>=$maxlen)return; $rsa = $this->getone($table,"`$afield`='$afid'","`id`,`$pfields`,`$jfield`"); if($rsa){ $this->joinarr[]=$rsa[$jfield]; $pid = $rsa[$pfields]; if($pid!=$afid)if($this->rows($table,"`$afield`='$pid'")>0)$this->getpvala($table,$pfields,$jfield,$pid,$afield,$maxlen); } } } class DB{ public static $tablename; public static function table($tab) { self::$tablename = ''.getconfig('.perfix.').$tab.''; return m($tab); } public static function where($f, $v) { } }