=')) { mysqli_report(MYSQLI_REPORT_OFF); } class DedeSqlite { var $linkID; var $dbHost; var $dbUser; var $dbPwd; var $dbName; var $dbPrefix; var $result; var $queryString; var $parameters; var $isClose; var $safeCheck; var $showError = true; var $recordLog = false; //记录日志到data/mysqli_record_log.inc便于进行调试 var $isInit = false; var $pconnect = false; var $_fixObject; //用外部定义的变量初始类,并连接数据库 function __construct($pconnect = FALSE, $nconnect = FALSE) { $this->isClose = FALSE; $this->safeCheck = TRUE; $this->pconnect = $pconnect; if ($nconnect) { $this->Init($pconnect); } } function DedeSql($pconnect = FALSE, $nconnect = TRUE) { $this->__construct($pconnect, $nconnect); } function Init($pconnect = FALSE) { $this->linkID = 0; //$this->queryString = ''; //$this->parameters = Array(); $this->dbHost = $GLOBALS['cfg_dbhost']; $this->dbUser = $GLOBALS['cfg_dbuser']; $this->dbPwd = $GLOBALS['cfg_dbpwd']; $this->dbName = $GLOBALS['cfg_dbname']; $this->dbPrefix = $GLOBALS['cfg_dbprefix']; $this->result["me"] = 0; $this->Open($pconnect); } //用指定参数初始数据库信息 function SetSource($host, $username, $pwd, $dbname, $dbprefix = "dede_") { $this->dbHost = $host; $this->dbUser = $username; $this->dbPwd = $pwd; $this->dbName = $dbname; $this->dbPrefix = $dbprefix; $this->result["me"] = 0; } //设置SQL里的参数 function SetParameter($key, $value) { $this->parameters[$key] = $value; } //连接数据库 function Open($pconnect = FALSE) { global $dsqlite; //连接数据库 if ($dsqlite && !$dsqlite->isClose && $dsqlite->isInit) { $this->linkID = $dsqlite->linkID; } else { $this->linkID = new SQLite3(DEDEDATA.'/'.$this->dbName.'.db'); //复制一个对象副本 CopySQLiPoint($this); } //处理错误,成功连接则选择数据库 if (!$this->linkID) { $this->DisplayError("系统提示:连接数据库失败,可能数据库密码不对或数据库服务器出错"); exit(); } $this->isInit = TRUE; return TRUE; } //为了防止采集等需要较长运行时间的程序超时,在运行这类程序时设置系统等待和交互时间 function SetLongLink() { //@mysqli_query("SET interactive_timeout=3600, wait_timeout=3600 ;", $this->linkID); } //获得错误描述 function GetError() { return $this->linkID->lastErrorMsg(); } //关闭数据库 //mysql能自动管理非持久连接的连接池 //实际上关闭并无意义并且容易出错,所以取消这函数 function Close($isok = FALSE) { $this->FreeResultAll(); if ($isok) { $this->linkID->close(); $this->isClose = TRUE; $GLOBALS['dsql'] = NULL; } } //定期清理死连接 function ClearErrLink() { } //关闭指定的数据库连接 function CloseLink($dblink) { } function Esc($_str) { global $dsqlite; if (!$dsqlite->isInit) { $this->Init($this->pconnect); } return $this->linkID->escapeString($_str); } //执行一个不返回结果的SQL语句,如update,delete,insert等 function ExecuteNoneQuery($sql = '') { global $dsqlite; if (!@$dsqlite->isInit) { $this->Init($this->pconnect); } if ($dsqlite->isClose) { $this->Open(FALSE); $dsqlite->isClose = FALSE; } if (!empty($sql)) { $this->SetQuery($sql); } else { return FALSE; } if (is_array($this->parameters)) { foreach ($this->parameters as $key => $value) { $this->queryString = str_replace("@".$key, "'$value'", $this->queryString); } } //SQL语句安全检查 if ($this->safeCheck) CheckSql($this->queryString, 'update'); $t1 = ExecTime(); $rs = $this->linkID->exec($this->queryString); if ($rs === false) { var_dump_cli("Error in fetch ".$this->linkID->lastErrorMsg().",SQL:{$this->queryString}"); } //查询性能测试 if ($this->recordLog) { $queryTime = ExecTime() - $t1; $this->RecordLog($queryTime); //echo $this->queryString."--{$queryTime}
\r\n"; } return $rs; } //执行一个返回影响记录条数的SQL语句,如update,delete,insert等 function ExecuteNoneQuery2($sql = '') { global $dsqlite; if (!$dsqlite->isInit) { $this->Init($this->pconnect); } if ($dsqlite->isClose) { $this->Open(FALSE); $dsqlite->isClose = FALSE; } if (!empty($sql)) { $this->SetQuery($sql); } if (is_array($this->parameters)) { foreach ($this->parameters as $key => $value) { $this->queryString = str_replace("@".$key, "'$value'", $this->queryString); } } $t1 = ExecTime(); $this->linkID->exec($this->queryString); //查询性能测试 if ($this->recordLog) { $queryTime = ExecTime() - $t1; $this->RecordLog($queryTime); //echo $this->queryString."--{$queryTime}
\r\n"; } return $this->linkID->changes(); } function ExecNoneQuery($sql = '') { return $this->ExecuteNoneQuery($sql); } function GetFetchRow($id = 'me') { return $this->result[$id]->numColumns(); } function GetAffectedRows() { return $this->linkID->changes(); } //执行一个带返回结果的SQL语句,如SELECT,SHOW等 function Execute($id = "me", $sql = '') { global $dsqlite; if (!@$dsqlite->isInit) { $this->Init($this->pconnect); } if ($dsqlite->isClose) { $this->Open(FALSE); $dsqlite->isClose = FALSE; } if (!empty($sql)) { $this->SetQuery($sql); } //SQL语句安全检查 if ($this->safeCheck) { CheckSql($this->queryString); } $t1 = ExecTime(); //var_dump($this->queryString); $this->result[$id] = $this->linkID->query($this->queryString); if (!$this->result[$id]) { $this->DisplayError("执行SQL错误:{$this->linkID->lastErrorMsg()}"); exit; } //var_dump(mysql_error()); //查询性能测试 if ($this->recordLog) { $queryTime = ExecTime() - $t1; $this->RecordLog($queryTime); //echo $this->queryString."--{$queryTime}
\r\n"; } if ($this->result[$id] === FALSE) { $this->DisplayError($this->linkID->lastErrorMsg()."
Error sql:".$this->queryString.""); } } function Query($id = "me", $sql = '') { $this->Execute($id, $sql); } //执行一个SQL语句,返回前一条记录或仅返回一条记录 function GetOne($sql = '', $acctype = SQLITE3_ASSOC) { global $dsqlite; if (!@$dsqlite->isInit) { $this->Init($this->pconnect); } if ($dsqlite->isClose) { $this->Open(FALSE); $dsqlite->isClose = FALSE; } if (!empty($sql)) { if (!preg_match("/LIMIT/i", $sql)) $this->SetQuery(preg_replace("/[,;]$/i", '', trim($sql))." LIMIT 0,1;"); else $this->SetQuery($sql); } $this->Execute("one"); $arr = $this->GetArray("one", $acctype); if (!is_array($arr)) { return ''; } else { $this->result["one"]->reset(); return ($arr); } } //执行一个不与任何表名有关的SQL语句,Create等 function ExecuteSafeQuery($sql, $id = "me") { global $dsqlite; if (!$dsqlite->isInit) { $this->Init($this->pconnect); } if ($dsqlite->isClose) { $this->Open(FALSE); $dsqlite->isClose = FALSE; } $this->result[$id] = $this->linkID->query($sql); } //返回当前的一条记录并把游标移向下一记录 //SQLITE3_ASSOC、SQLITE3_NUM、SQLITE3_BOTH function GetArray($id = "me", $acctype = SQLITE3_ASSOC) { switch ($acctype) { case MYSQL_ASSOC: $acctype = SQLITE3_ASSOC; break; case MYSQL_NUM: $acctype = SQLITE3_NUM; break; default: $acctype = SQLITE3_BOTH; break; } if ($this->result[$id] === 0) { return FALSE; } else { $rs = $this->result[$id]->fetchArray($acctype); if (!$rs) { $this->result[$id] = 0; return false; } return $rs; } } function GetObject($id = "me") { if (!isset($this->_fixObject[$id])) { $this->_fixObject[$id] = array(); while ($row = $this->result[$id]->fetchArray(SQLITE3_ASSOC)) { $this->_fixObject[$id][] = (object)$row; } $this->result[$id]->reset(); } return array_shift($this->_fixObject[$id]); } //检测是否存在某数据表 function IsTable($tbname) { global $dsqlite; if (!$dsqlite->isInit) { $this->Init($this->pconnect); } $prefix = "#@__"; $tbname = str_replace($prefix, $GLOBALS['cfg_dbprefix'], $tbname); $row = $this->linkID->querySingle("PRAGMA table_info({$tbname});"); if ($row !== null) { return TRUE; } return FALSE; } //获得MySql的版本号 function GetVersion($isformat = TRUE) { global $dsqlite; if (!@$dsqlite->isInit) { $this->Init($this->pconnect); } if ($dsqlite->isClose) { $this->Open(FALSE); $dsqlite->isClose = FALSE; } $rs = $this->linkID->querySingle("select sqlite_version();"); $sqlite_version = $rs; if ($isformat) { $sqlite_versions = explode(".", trim($sqlite_version)); $sqlite_version = number_format($sqlite_versions[0].".".$sqlite_versions[1], 2); } return $sqlite_version; } //获取特定表的信息 function GetTableFields($tbname, $id = "me") { global $dsqlite; if (!$dsqlite->isInit) { $this->Init($this->pconnect); } $prefix = "#@__"; $tbname = str_replace($prefix, $GLOBALS['cfg_dbprefix'], $tbname); $query = "SELECT * FROM {$tbname} LIMIT 0,1"; $this->result[$id] = $this->linkID->query($query); } //获取字段详细信息 function GetFieldObject($id = "me") { $cols = $this->result[$id]->numColumns(); $fields = array(); while ($row = $this->result[$id]->fetchArray()) { for ($i = 1; $i < $cols; $i++) { $fields[] = $this->result[$id]->columnName($i); } } return (object)$fields; } //获得查询的总记录数 function GetTotalRow($id = "me") { $queryString = preg_replace("/SELECT(.*)FROM/isU", 'SELECT count(*) as dd FROM', $this->queryString); $rs = $this->linkID->query($queryString); $row = $rs->fetchArray(); return $row['dd']; } //获取上一步INSERT操作产生的id function GetLastID() { //如果 AUTO_INCREMENT 的列的类型是 BIGINT,则 mysqli_insert_id() 返回的值不正确 //可以在 SQL 查询中用 MySQL 内部的 SQL 函数 LAST_INSERT_ID() 来替代 //$rs = mysqli_query($this->linkID, "Select LAST_INSERT_ID() as lid"); //$row = mysqli_fetch_array($rs); //return $row["lid"]; return $this->linkID->lastInsertRowID(); } //释放记录集占用的资源 function FreeResult($id = "me") { if ($this->result[$id]) { @$this->result[$id]->reset(); } } function FreeResultAll() { if (!is_array($this->result)) { return ''; } foreach ($this->result as $kk => $vv) { if ($vv) { @$vv->reset(); } } } //设置SQL语句,会自动把SQL语句里的#@__替换为$this->dbPrefix(在配置文件中为$cfg_dbprefix) function SetQuery($sql) { $prefix = "#@__"; $sql = str_replace($prefix, $GLOBALS['cfg_dbprefix'], $sql); $this->queryString = $sql; //$this->queryString = preg_replace("/CONCAT\(',', arc.typeid2, ','\)/i","printf(',%s,', arc.typeid2)",$this->queryString); if (preg_match("/CONCAT\(([^\)]*?)\)/i", $this->queryString, $matches)) { $this->queryString = preg_replace("/CONCAT\(([^\)]*?)\)/i", str_replace(",", "||", $matches[1]), $this->queryString); $this->queryString = str_replace("'||'", "','", $this->queryString); } $this->queryString = preg_replace("/FIND_IN_SET\('([\w]+)', arc.flag\)>0/i", "(',' || arc.flag || ',') LIKE '%,\\1,%'", $this->queryString); $this->queryString = preg_replace("/FIND_IN_SET\('([\w]+)', arc.flag\)<1/i", "(',' || arc.flag || ',') NOT LIKE '%,\\1,%'", $this->queryString); if (preg_match("/CREATE TABLE/i", $this->queryString)) { $this->queryString = preg_replace("/[\r\n]/", '', $this->queryString); $this->queryString = preg_replace('/character set (.*?) /i', '', $this->queryString); $this->queryString = preg_replace('/unsigned/i', '', $this->queryString); $this->queryString = str_replace('TYPE=MyISAM', '', $this->queryString); $this->queryString = preg_replace('/TINYINT\(([\d]+)\)/i', 'INTEGER', $this->queryString); $this->queryString = preg_replace('/mediumint\(([\d]+)\)/i', 'INTEGER', $this->queryString); $this->queryString = preg_replace('/smallint\(([\d]+)\)/i', 'INTEGER', $this->queryString); $this->queryString = preg_replace('/int\(([\d]+)\)/i', 'INTEGER', $this->queryString); $this->queryString = preg_replace('/auto_increment/i', 'PRIMARY KEY AUTOINCREMENT', $this->queryString); $this->queryString = preg_replace('/, KEY(.*?)MyISAM;/i', '', $this->queryString); $this->queryString = preg_replace('/, KEY(.*?);/i', ');', $this->queryString); $this->queryString = preg_replace('/, UNIQUE KEY(.*?);/i', ');', $this->queryString); $this->queryString = preg_replace('/set\(([^\)]*?)\)/', 'varchar', $this->queryString); $this->queryString = preg_replace('/enum\(([^\)]*?)\)/', 'varchar', $this->queryString); if (preg_match("/PRIMARY KEY AUTOINCREMENT/", $this->queryString)) { $this->queryString = preg_replace('/,([\t\s ]+)PRIMARY KEY \(`([0-9a-zA-Z]+)`\)/i', '', $this->queryString); $this->queryString = str_replace(', PRIMARY KEY (`id`)', '', $this->queryString); } } $this->queryString = preg_replace("/SHOW fields FROM `([\w]+)`/i", "PRAGMA table_info('\\1') ", $this->queryString); $this->queryString = preg_replace("/SHOW CREATE TABLE .([\w]+)/i", "SELECT 0,sql FROM sqlite_master WHERE name='\\1'; ", $this->queryString); //var_dump($this->queryString); $this->queryString = preg_replace("/Show Tables/i", "SELECT name FROM sqlite_master WHERE type = \"table\"", $this->queryString); $this->queryString = str_replace("\'", "\"", $this->queryString); $this->queryString = str_replace('\t\n', "", $this->queryString); //var_dump($this->queryString); } function SetSql($sql) { $this->SetQuery($sql); } function RecordLog($runtime = 0) { global $cfg_cookie_encode; $enkey = substr(md5(substr($cfg_cookie_encode.'dedebiz', 0, 5)), 0, 10); $RecordLogFile = DEDEDATA.'/mysqli_record_log_'.$enkey.'.inc'; $url = $this->GetCurUrl(); $savemsg = <<queryString} Page:$url Runtime:$runtime EOT; $fp = @fopen($RecordLogFile, 'a'); @fwrite($fp, $savemsg); @fclose($fp); } //显示数据链接错误信息 function DisplayError($msg) { global $cfg_cookie_encode; $enkey = substr(md5(substr($cfg_cookie_encode.'dedebiz', 0, 5)), 0, 10); $errorTrackFile = DEDEDATA.'/sqlite_error_trace_'.$enkey.'.inc'; if ($this->showError) { $msg = str_replace(array("\r","\n"),"",addslashes($msg)); ShowMsg("{$msg}", "javascript:;", -1); exit; } $savemsg = 'Page: '.$this->GetCurUrl()."\r\nError: ".$msg."\r\nTime".date('Y-m-d H:i:s'); //保存SQLite错误日志 $fp = @fopen($errorTrackFile, 'a'); @fwrite($fp, '<'.'?php exit();'."\r\n/*\r\n{$savemsg}\r\n*/\r\n?".">\r\n"); @fclose($fp); } //获得当前的脚本网址 function GetCurUrl() { if (!empty($_SERVER["REQUEST_URI"])) { $scriptName = $_SERVER["REQUEST_URI"]; $nowurl = $scriptName; } else { $scriptName = $_SERVER["PHP_SELF"]; if (empty($_SERVER["QUERY_STRING"])) { $nowurl = $scriptName; } else { $nowurl = $scriptName."?".$_SERVER["QUERY_STRING"]; } } return $nowurl; } } //复制一个对象副本 function CopySQLiPoint(&$ndsql) { $GLOBALS['dsqlite'] = $ndsql; } ?>