_config = $pConfig; # 通过主键取出数据 if($pPK && $pPK = abs($pPK)){ if($tRow = $this->fRow($pPK)){ foreach($tRow as $k1 => $v1){ $this->$k1 = $v1; } } else{ foreach($this->field as $k1 => $v1){ $this->$k1 = false; } } } } /** * 特殊方法实现 * @param string $pMethod * @param array $pArgs * @return mixed */ public function __call($pMethod, $pArgs){ # 连贯操作的实现 if(in_array($pMethod, array('field', 'table', 'where', 'order', 'limit', 'page', 'having', 'group', 'lock', 'distinct'), true)){ $this->options[$pMethod] = $pArgs[0]; return $this; } # 统计查询的实现 if(in_array($pMethod, array('count', 'sum', 'min', 'max', 'avg'))){ $field = isset($pArgs[0])? $pArgs[0]: '*'; return $this->fOne("$pMethod($field)"); } # 根据某个字段获取记录 if('ff' == substr($pMethod, 0, 2)){ return $this->where(strtolower(substr($pMethod, 2)) . "='{$pArgs[0]}'")->fRow(); } } /** * 数据库连接 */ static function &instance($pConfig = 'default'){ if(empty(self::$instance[$pConfig])){ # 实例化PDO $tDB = Yaf_Registry::get("config")->db->$pConfig->toArray(); self::$instance[$pConfig] = @new PDO($tDB['dsn'], $tDB['username'], $tDB['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4")); } return self::$instance[$pConfig]; } /** * 过滤危险数据 * @param array $pData */ private function _filter(&$pData){ foreach($pData as $k1 => &$v1){ if(empty($this->field[$k1])){ unset($pData[$k1]); continue; } if(is_array($v1)){ $v1 = $v1[0]; }else{ $v1 = strtr($v1, array('\\' => '', "'" => "\'")); } } return $pData? true: false; } /** * 查询参数 * @param mixed $pOpt */ private function _options($pOpt = array()){ # 合并查询条件 $tOpt = $pOpt? array_merge($this->options, $pOpt): $this->options; $this->options = array(); # 数据表 empty($tOpt['table']) && $tOpt['table'] = $this->table; empty($tOpt['field']) && $tOpt['field'] = '*'; # 查询条件 if(isset($tOpt['where']) && is_array($tOpt['where'])){ foreach($tOpt['where'] as $k1 => $v1) { if(isset($this->field[$k1]) && is_scalar($v1)){ # 整型格式化 if(false !== strpos($this->field[$k1]['type'], 'int')){ $tOpt['where'][$k1] = intval($v1); } # 浮点格式化 elseif(false !== strpos($this->field[$k1]['type'], 'decimal')){ $tOpt['where'][$k1] = floatval($v1); } } } } return $tOpt; } /** * 执行SQL */ function exec($pSql){ $this->db = &self::instance($this->_config); if($tReturn = $this->db->exec($pSql)){ #if($this->db->exec($pSql)){ # $tReturn = $this->db->lastInsertId(); $this->error = array(); }else{ $this->error = $this->db->errorInfo(); isset($this->error[1]) || $this->error = array(); } return $tReturn; } /** * 设置出错信息 * @param $pMsg 信息 * @param int $pCode 错误码 * @param string $pState SQL错误码 */ function setError($pMsg, $pCode = 1, $pState = 'BTC001'){ $this->error = array($pState, $pCode, $pMsg); return false; } /** * 开启本次查询缓存 * @param str $pKey MemKey * @param int $pExpire 有效期 */ private $cache = array(); function cache($pKey = 'md5', $pExpire = 86400){ $this->cache['key'] = $pKey; $this->cache['expire'] = $pExpire; return $this; } /** * 执行SQL,并返回结果 */ function query(){ $tArgs = func_get_args(); $tSql = array_shift($tArgs); # 锁表查询 if($this->_lock) { $tSql.= ' '.$this->_lock; $this->_lock = ''; } # 使用缓存 if($this->cache){ $tMem = &Cache_Memcache::instance('default'); if('md5' == $this->cache['key']){ $this->cache['key'] = md5($tSql . ($tArgs? join(',', $tArgs): '')); } if(false !== ($tData = $tMem->get($this->cache['key']))){ return $tData; } } # 查询数据库 $this->db = &self::instance($this->_config); if($tArgs){ $tQuery = $this->db->prepare($tSql); $tQuery->execute($tArgs); } else{ $tQuery = $this->db->query($tSql); } if(!$tQuery) { $this->error = $this->db->errorInfo(); isset($this->error[1]) || $this->error = array(); return array(); } # 不缓存查询结果 if(!$this->cache){ return $tQuery->fetchAll(PDO::FETCH_ASSOC); } # 设置缓存 $tData = $tQuery->fetchAll(PDO::FETCH_ASSOC); $tMem->set($this->cache['key'], $tData, 0, $this->cache['expire']); $this->cache = array(); return $tData; } /** * 保存记录(自动区分 增/改) */ function save($pData){ return isset($pData[$this->pk])? $this->update($pData): $this->insert($pData); } /** * 添加记录 * return lastid */ function insert($pData, $pReplace = false){ if($this->_filter($pData)){ $tField = '`'.join('`,`', array_keys($pData)).'`'; $tVal = join("','", $pData); // echo ($pReplace? "REPLACE": "INSERT") . " INTO $this->table($tField) VALUES ('$tVal')";exit(); #Tool_Fnc::writefile('/home/zhangyueru/xx',$tSql); if($this->exec(($pReplace? "REPLACE": "INSERT") . " INTO $this->table($tField) VALUES ('$tVal')")){ return $this->db->lastInsertId(); } } return 0; } /** * 更新记录 */ function update($pData){ # 过滤 if(!$this->_filter($pData)) return false; # 条件 $tOpt = array(); if(isset($pData[$this->pk])){ $tOpt = array('where' => "$this->pk='{$pData[$this->pk]}'"); } $tOpt = $this->_options($tOpt); # 更新 if($pData && !empty($tOpt['where'])){ foreach($pData as $k1 => $v1){ $tSet[] = "`$k1`='$v1'"; } $tSql = "UPDATE `" . $tOpt['table'] . "` SET " . join(',', $tSet) . " WHERE " . $tOpt['where']; # Tool_Fnc::writefile('/home/zhangyueru/xx',$tSql); return $this->exec("UPDATE " . $tOpt['table'] . " SET " . join(',', $tSet) . " WHERE " . $tOpt['where']); } return false; } /** * 删除记录 */ function del(){ if($tArgs = func_get_args()){ # 主键删除 $tSql = "DELETE FROM $this->table WHERE "; if(intval($tArgs[0]) || count($tArgs) > 1){ return $this->exec($tSql.$this->pk . ' IN(' . join(',', array_map("intval", $tArgs)) . ')'); } # 条件删除 false === strpos($tArgs[0], '=') && exit('删除条件错误!'); return $this->exec($tSql . $tArgs[0]); } # 连贯删除 $tOpt = $this->_options(); if(empty($tOpt['where'])) return false; return $this->exec("DELETE FROM " . $tOpt['table'] . " WHERE " . $tOpt['where']); } /** * 查找一条 */ function fRow($pId = 0){ if(false === stripos($pId, 'SELECT')){ $tOpt = $pId? $this->_options(array('where' => $this->pk . '=' . abs($pId))): $this->_options(); $tOpt['where'] = empty($tOpt['where'])? '': ' WHERE ' . $tOpt['where']; $tOpt['order'] = empty($tOpt['order'])? '': ' ORDER BY ' . $tOpt['order']; $tSql = "SELECT {$tOpt['field']} FROM {$tOpt['table']} {$tOpt['where']} {$tOpt['order']} LIMIT 0,1"; } else { $tSql = &$pId; } // echo $tSql;echo "\r\n"; if($tResult = $this->query($tSql)){ return $tResult[0]; } return array(); } /** * 查找一字段 ( 基于 fRow ) * * @param string $pField * @return string */ function fOne($pField){ $this->field($pField); if(($tRow = $this->fRow()) && isset($tRow[$pField])){ return $tRow[$pField]; } return false; } /** * 查找多条 */ function fList($pOpt = array()){ if(!is_array($pOpt)){ $pOpt = array('where' => $this->pk . (strpos($pOpt, ',')? ' IN(' . $pOpt . ')': '=' . $pOpt)); } $tOpt = $this->_options($pOpt); $tSql = "SELECT {$tOpt['field']} FROM {$tOpt['table']}"; $this->join && $tSql .= implode(' ', $this->join); empty($tOpt['where']) || $tSql .= ' WHERE ' . $tOpt['where']; empty($tOpt['group']) || $tSql .= ' GROUP BY ' . $tOpt['group']; empty($tOpt['order']) || $tSql .= ' ORDER BY ' . $tOpt['order']; empty($tOpt['having']) || $tSql.= ' HAVING '.$tOpt['having']; empty($tOpt['limit']) || $tSql .= ' LIMIT ' . $tOpt['limit']; #echo $tSql; return $this->query($tSql); } /** * 查询并处理为哈西数组 ( 基于 fList ) * * @param string $pField * @return array */ function fHash($pField){ $this->field($pField); $tList = array(); $tField = explode(',', $pField); if(2 == count($tField)) foreach($this->fList() as $v1) $tList[$v1[$tField[0]]] = $v1[$tField[1]]; else foreach($this->fList() as $v1) $tList[$v1[$tField[0]]] = $v1; return $tList; } /** * 库 > (所有)数据表 * @return array */ function getTables(){ $this->db = &self::instance($this->_config); return $this->db->query("SHOW TABLES")->fetchAll(3); } /** * 数据表 > (所有)字段 * @return array */ function getFields($pTable){ $this->db = &self::instance($this->_config); $tQuery = $this->db->query("SHOW FULL FIELDS FROM `$pTable`"); return $tQuery? $tQuery->fetchAll(2): array(); } public $join = array(); function join($pTable, $pWhere, $pPrefix = ''){ $this->join[] = " $pPrefix JOIN `$pTable` ON $pWhere "; return $this; } /** * 事务开始 */ private $_begin_transaction = false; function begin(){ $this->db || $this->db = &self::instance($this->_config); # 已经有事务,退出事务 $this->back(); if(!$this->db->beginTransaction()){ return false; } $this->_begin_transaction = true; return true; } /** * 事务提交 */ function commit(){ if($this->_begin_transaction) { $this->_begin_transaction = false; $this->db->commit(); } return true; } /** * 事务回滚 */ function back(){ if($this->_begin_transaction) { $this->_begin_transaction = false; $this->db->rollback(); } return false; } /** * 锁表 */ function lock($pSql = 'FOR UPDATE'){ $this->_lock = $pSql; return $this; } }