linkdb = false; $this->dbpst = $dbpst; $this->error = ''; $this->lock = false; } /** * 连接到服务器。 */ function connect() { if ($this->linkdb !== false) return $this->linkdb; $cfg = webini('db' . $this->dbpst); if (is_string($cfg)) die($cfg); $this->linkdb = new pdo($cfg, $this->pf); $this->linkdb->connect(); return $this->linkdb; } /** * 获取一条数据。 * 返回array(),无数据返回null,出错返回false * csql SQL拼接类 * 例: * $csql = new \ciy\sql(); * $csql->... * $row = $mydata->getone($csql); * if(is_array($row)) * $row['username']... */ function getone($csql) { $limit = $csql->limit; if (empty($limit)) $limit = ' limit 1'; if ($this->lock) $limit .= ' for update'; $ret = $this->connect()->get(2, $csql->buildsql() . $limit, $csql->tsmt); if ($ret === false || $ret === null) return $this->errdata($ret); return $ret; } /** * 获取一条数据的单个字段。 * 返回变量,无数据返回null,出错返回false * csql SQL拼接类 * 例: * $csql = new \ciy\sql(); * $usercount = toint($mydata->get1($csql)); * $csql->column('name'); * $username = $mydata->get1($csql); */ function get1($csql) { if ($csql->column == '*') $csql->column = 'count(*)'; $limit = $csql->limit; if (empty($limit)) $limit = ' limit 1'; if ($this->lock) $limit .= ' for update'; $ret = $this->connect()->get(3, $csql->buildsql() . $limit, $csql->tsmt); if ($ret === false || $ret === null) return $this->errdata($ret); return $ret; } /** * 获取数据集合。 * 返回array(),出错返回false * 判断is_array,确认数据有效 * csql SQL拼接类 * pageno 第pageno页,不分页传null,默认null * pagecount 每页pagecount条,默认20 * rowcount 返回总数据条数(数据量大,查询耗时较高),不填不查询。 * 例: * $rows = $mydata->get($csql);//查询全部数据 * $rows = $mydata->get($csql,1,$pagecount,$rowcount); * if(is_array($rows)){ * foreach($rows as $row) * $row['username']... * } */ function get($csql, &$rowcount = 0) { //$pageno=null 查询全部 $sql = $csql->buildsql(); $limit = $csql->limit; if ($this->lock) $limit .= ' for update'; $ret = $this->connect()->get(1, $sql . $limit, $csql->tsmt); if ($ret === false) return $this->errdata($ret); if ($rowcount == -1) { $column = $csql->column; $csql->column = 'count(*)'; $rowcount = toint($this->connect()->get(3, $csql->buildsql(), $csql->tsmt)); $csql->column = $column; } return $ret; } /** * 原始参数获取数据集合。 * 返回array(),出错返回false * sql SQL prepare字符串 * tsmt array ?对应数据集 * 例: * $row = $mydata->getraw('select * from xxx where id=?',[3]); */ function getraw($sql, $tsmt = array()) { $ret = $this->connect()->get(1, $sql, $tsmt); if ($ret === false) return $this->errdata($ret); return $ret; } function getfield(&$field, $table) { $fieldrows = $this->connect()->get(1, 'show full fields from ' . $table, array()); if ($fieldrows === false) return $this->errdata($fieldrows); $sorts = array(); foreach ($fieldrows as $fr) { if (!empty($fr['Comment'])) $sorts[] = $fr['Field']; $field[$fr['Field']] = array('c' => $fr['Comment']); } return implode(',', $sorts); } function getdbcodes($table, $field) { $fieldrow = $this->connect()->get(1, 'show full fields from ' . $table . ' where Field=?', array($field)); if (count($fieldrow) == 0) return array(); $comment = $fieldrow[0]['Comment']; $ret = array(); $ind = strpos($comment, ',TINT'); if ($ind !== false) { $exts = explode('|', substr($comment, $ind + 6)); $exts = explode('.', $exts[0]); for ($i = 0; $i < count($exts); $i++) { $excos = explode(':', $exts[$i]); if (count($excos) > 1) { $ret[] = array('id' => $excos[0], 'name' => $excos[1]); } else if (!empty($excos[0])) { $ret[] = array('id' => $i, 'name' => $excos[0]); } } return $ret; } $ind = strpos($comment, ',TBIN'); if ($ind !== false) { $exts = explode('|', substr($comment, $ind + 6)); $exts = explode('.', $exts[0]); for ($i = 0; $i < count($exts); $i++) { $excos = explode('.', $exts[$i]); $ret[] = array('id' => $i + 1, 'name' => $exts[$i]); } return $ret; } $ind = strpos($comment, ',BOOL'); if ($ind !== false) { $exts = explode('.', substr($comment, $ind + 6)); if (count($exts) == 1) $exts[1] = ''; $ret[] = array('id' => 1, 'name' => empty($exts[0]) ? '✔' : $exts[0]); $ret[] = array('id' => 2, 'name' => empty($exts[1]) ? '✘' : $exts[1]); return $ret; } return $ret; } function insert_id() { return $this->connect(true)->insert_id(); } function insert($csql, $updata) { $ret = $this->connect(true)->insert($csql, $updata); if ($ret === false) return $this->errdata($ret); return $ret; } function update($csql, $updata) { $ret = $this->connect(true)->update($csql, $updata); if ($ret === false) return $this->errdata($ret); return $ret; } /** * 删除表数据,支持备份到_bak。(注意_bak建表时,应去掉id的自增属性) * 成功返回影响行数,失败返回false * csql SQL拼接类 * backup false:直接删除;true:先备份到table_bak,再删除。 * 例: * $affected = $mydata->delete($csql,true);//备份后删除 */ function delete($csql, $backup = false) { if ($backup) { $fields = $this->connect(true)->get(1, 'show full fields from ' . $csql->table, array()); $fieldlts = array(); if ($fields === false) return $this->errdata($fields); foreach ($fields as $row) $fieldlts[] = $row['Field']; $fieldlt = implode(',', $fieldlts); $sql = "insert into {$csql->table}_bak ({$fieldlt}) select {$fieldlt} from {$csql->table}" . $csql->buildwhere(); $ret = $this->connect(true)->execute($sql, $csql->tsmt); if ($ret === false) return $this->errdata($ret); } $ret = $this->connect(true)->execute("delete from {$csql->table}" . $csql->buildwhere(), $csql->tsmt); if ($ret === false) return $this->errdata($ret); return $ret; } /** * 执行SQL语句。 * 成功返回影响行数,失败返回false * sql SQL语句。 * 例: * $affected = $mydata->execute('update users set username=? where id=?',['aaa',12]); */ function execute($sql, $tsmt = array()) { $ret = $this->connect(true)->execute($sql, $tsmt); if ($ret === false) return $this->errdata($ret); return $ret; } function begin() { $ret = $this->connect(true)->begin(); if ($ret === false) return $this->errdata($ret); $this->lock = true; return $ret; } function commit() { $ret = $this->connect(true)->commit(); if ($ret === false) return $this->errdata($ret); $this->lock = false; _setmemvar($this, 'func_commit', array('params+1')); return $ret; } function rollback() { $ret = $this->connect(true)->rollback(); if ($ret === false) return $this->errdata($ret); $this->lock = false; _setmemvar($this, 'func_rollback', array('params+1')); return $ret; } function tran($func) { if (!($func instanceof \Closure)) { $this->error = '没有传递正确的闭包函数'; return false; } $this->begin(); $ret = false; try { $ret = $func(); } catch (\Exception $ex) { $ret = false; $this->error = $ex->getMessage(); } if ($ret === false) $this->rollback(); else $this->commit(); return $ret; } function errdata($ret) { if ($this->linkdb !== false) $this->error = $this->linkdb->error; return $ret; } function trace($pf, $rsuser = null) { //traceid全链路跟踪 if (!preg_match('/^[A-Z]{2}\d{13}_\d{8}$/', $pf)) //防止前端攻击 $pf = 'ER' . time() . '000_' . rand(10000000, 99999999); $time = substr($pf, 2, 10); if (abs(time() - $time) > 10) //跟随服务器时间 $pf .= ',svrt=' . time(); if (is_array($rsuser)) $this->pf = $pf . ',ip=' . getip() . ',uid=' . $rsuser['id']; else $this->pf = $pf . ',ip=' . getip() . ',uid=no'; } function __destruct() { } }