国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

719 lines
21KB

  1. <?php if(!defined('DEDEINC')) exit("Request Error!");
  2. /**
  3. * 数据库类
  4. * 说明:系统底层数据库核心类
  5. * 调用这个类前,请先设定这些外部变量
  6. * $GLOBALS['cfg_dbhost'];
  7. * $GLOBALS['cfg_dbuser'];
  8. * $GLOBALS['cfg_dbpwd'];
  9. * $GLOBALS['cfg_dbname'];
  10. * $GLOBALS['cfg_dbprefix'];
  11. *
  12. * @version $Id: dedesqli.class.php 1 15:00 2011-1-21 tianya $
  13. * @package DedeCMS.Libraries
  14. * @copyright Copyright (c) 2007 - 2019, DesDev, Inc.
  15. * @license http://help.dedecms.com/usersguide/license.html
  16. * @link http://www.dedecms.com
  17. */
  18. @set_time_limit(0);
  19. // 在工程所有文件中均不需要单独初始化这个类,可直接用 $dsql 或 $db 进行操作
  20. // 为了防止错误,操作完后不必关闭数据库
  21. $dsql = $dsqli = $db = new DedeSqli(FALSE);
  22. /**
  23. * Dede MySQLi数据库类
  24. *
  25. * @package DedeSqli
  26. * @subpackage DedeCMS.Libraries
  27. * @link http://www.dedecms.com
  28. */
  29. if (!defined('MYSQL_BOTH')) {
  30. define('MYSQL_BOTH',MYSQLI_BOTH);
  31. }
  32. class DedeSqli
  33. {
  34. var $linkID;
  35. var $dbHost;
  36. var $dbUser;
  37. var $dbPwd;
  38. var $dbName;
  39. var $dbPrefix;
  40. var $result;
  41. var $queryString;
  42. var $parameters;
  43. var $isClose;
  44. var $safeCheck;
  45. var $showError=false;
  46. var $recordLog=false; // 记录日志到data/mysqli_record_log.inc便于进行调试
  47. var $isInit=false;
  48. var $pconnect=false;
  49. //用外部定义的变量初始类,并连接数据库
  50. function __construct($pconnect=FALSE,$nconnect=FALSE)
  51. {
  52. $this->isClose = FALSE;
  53. $this->safeCheck = TRUE;
  54. $this->pconnect = $pconnect;
  55. if($nconnect)
  56. {
  57. $this->Init($pconnect);
  58. }
  59. }
  60. function DedeSql($pconnect=FALSE,$nconnect=TRUE)
  61. {
  62. $this->__construct($pconnect,$nconnect);
  63. }
  64. function Init($pconnect=FALSE)
  65. {
  66. $this->linkID = 0;
  67. //$this->queryString = '';
  68. //$this->parameters = Array();
  69. $this->dbHost = $GLOBALS['cfg_dbhost'];
  70. $this->dbUser = $GLOBALS['cfg_dbuser'];
  71. $this->dbPwd = $GLOBALS['cfg_dbpwd'];
  72. $this->dbName = $GLOBALS['cfg_dbname'];
  73. $this->dbPrefix = $GLOBALS['cfg_dbprefix'];
  74. $this->result["me"] = 0;
  75. $this->Open($pconnect);
  76. }
  77. //用指定参数初始数据库信息
  78. function SetSource($host,$username,$pwd,$dbname,$dbprefix="dede_")
  79. {
  80. $this->dbHost = $host;
  81. $this->dbUser = $username;
  82. $this->dbPwd = $pwd;
  83. $this->dbName = $dbname;
  84. $this->dbPrefix = $dbprefix;
  85. $this->result["me"] = 0;
  86. }
  87. function SelectDB($dbname)
  88. {
  89. mysql_select_db($dbname);
  90. }
  91. //设置SQL里的参数
  92. function SetParameter($key,$value)
  93. {
  94. $this->parameters[$key]=$value;
  95. }
  96. //连接数据库
  97. function Open($pconnect=FALSE)
  98. {
  99. global $dsqli;
  100. //连接数据库
  101. if($dsqli && !$dsqli->isClose && $dsqli->isInit)
  102. {
  103. $this->linkID = $dsqli->linkID;
  104. }
  105. else
  106. {
  107. $i = 0;
  108. @list($dbhost, $dbport) = explode(':', $this->dbHost);
  109. !$dbport && $dbport = 3306;
  110. $this->linkID = mysqli_init();
  111. mysqli_real_connect($this->linkID, $dbhost, $this->dbUser, $this->dbPwd, false, $dbport);
  112. mysqli_errno($this->linkID) != 0 && $this->DisplayError('DedeCMS错误警告: 链接('.$this->pconnect.') 到MySQL发生错误');
  113. //复制一个对象副本
  114. CopySQLiPoint($this);
  115. }
  116. //处理错误,成功连接则选择数据库
  117. if(!$this->linkID)
  118. {
  119. $this->DisplayError("DedeCMS错误警告:<font color='red'>连接数据库失败,可能数据库密码不对或数据库服务器出错!</font>");
  120. exit();
  121. }
  122. $this->isInit = TRUE;
  123. $serverinfo = mysqli_get_server_info($this->linkID);
  124. if ($serverinfo > '4.1' && $GLOBALS['cfg_db_language'])
  125. {
  126. mysqli_query($this->linkID, "SET character_set_connection=" . $GLOBALS['cfg_db_language'] . ",character_set_results=" . $GLOBALS['cfg_db_language'] . ",character_set_client=binary");
  127. }
  128. if ($serverinfo > '5.0') {
  129. mysqli_query($this->linkID, "SET sql_mode=''");
  130. }
  131. if ($this->dbName && !@mysqli_select_db($this->linkID, $this->dbName)) {
  132. $this->DisplayError('无法使用数据库');
  133. }
  134. return TRUE;
  135. }
  136. //为了防止采集等需要较长运行时间的程序超时,在运行这类程序时设置系统等待和交互时间
  137. function SetLongLink()
  138. {
  139. @mysqli_query("SET interactive_timeout=3600, wait_timeout=3600 ;", $this->linkID);
  140. }
  141. //获得错误描述
  142. function GetError()
  143. {
  144. $str = mysqli_error($this->linkID);
  145. return $str;
  146. }
  147. //关闭数据库
  148. //mysql能自动管理非持久连接的连接池
  149. //实际上关闭并无意义并且容易出错,所以取消这函数
  150. function Close($isok=FALSE)
  151. {
  152. $this->FreeResultAll();
  153. if($isok)
  154. {
  155. @mysqli_close($this->linkID);
  156. $this->isClose = TRUE;
  157. $GLOBALS['dsql'] = NULL;
  158. }
  159. }
  160. //定期清理死连接
  161. function ClearErrLink()
  162. {
  163. }
  164. //关闭指定的数据库连接
  165. function CloseLink($dblink)
  166. {
  167. @mysqli_close($dblink);
  168. }
  169. function Esc( $_str )
  170. {
  171. if ( version_compare( phpversion(), '4.3.0', '>=' ) )
  172. {
  173. return @mysqli_real_escape_string($this->linkID, $_str );
  174. } else {
  175. return @mysqli_escape_string ($this->linkID, $_str );
  176. }
  177. }
  178. //执行一个不返回结果的SQL语句,如update,delete,insert等
  179. function ExecuteNoneQuery($sql='')
  180. {
  181. global $dsqli;
  182. if(!$dsqli->isInit)
  183. {
  184. $this->Init($this->pconnect);
  185. }
  186. if($dsqli->isClose)
  187. {
  188. $this->Open(FALSE);
  189. $dsqli->isClose = FALSE;
  190. }
  191. if(!empty($sql))
  192. {
  193. $this->SetQuery($sql);
  194. }else{
  195. return FALSE;
  196. }
  197. if(is_array($this->parameters))
  198. {
  199. foreach($this->parameters as $key=>$value)
  200. {
  201. $this->queryString = str_replace("@".$key,"'$value'",$this->queryString);
  202. }
  203. }
  204. //SQL语句安全检查
  205. if($this->safeCheck) CheckSql($this->queryString,'update');
  206. $t1 = ExecTime();
  207. $rs = mysqli_query($this->linkID, $this->queryString);
  208. //查询性能测试
  209. if($this->recordLog) {
  210. $queryTime = ExecTime() - $t1;
  211. $this->RecordLog($queryTime);
  212. //echo $this->queryString."--{$queryTime}<hr />\r\n";
  213. }
  214. return $rs;
  215. }
  216. //执行一个返回影响记录条数的SQL语句,如update,delete,insert等
  217. function ExecuteNoneQuery2($sql='')
  218. {
  219. global $dsqli;
  220. if(!$dsqli->isInit)
  221. {
  222. $this->Init($this->pconnect);
  223. }
  224. if($dsqli->isClose)
  225. {
  226. $this->Open(FALSE);
  227. $dsqli->isClose = FALSE;
  228. }
  229. if(!empty($sql))
  230. {
  231. $this->SetQuery($sql);
  232. }
  233. if(is_array($this->parameters))
  234. {
  235. foreach($this->parameters as $key=>$value)
  236. {
  237. $this->queryString = str_replace("@".$key,"'$value'",$this->queryString);
  238. }
  239. }
  240. $t1 = ExecTime();
  241. mysqli_query($this->linkID, $this->queryString);
  242. //查询性能测试
  243. if($this->recordLog) {
  244. $queryTime = ExecTime() - $t1;
  245. $this->RecordLog($queryTime);
  246. //echo $this->queryString."--{$queryTime}<hr />\r\n";
  247. }
  248. return mysqli_affected_rows($this->linkID);
  249. }
  250. function ExecNoneQuery($sql='')
  251. {
  252. return $this->ExecuteNoneQuery($sql);
  253. }
  254. function GetFetchRow($id='me')
  255. {
  256. return @mysqli_fetch_row($this->result[$id]);
  257. }
  258. function GetAffectedRows()
  259. {
  260. return mysqli_affected_rows($this->linkID);
  261. }
  262. //执行一个带返回结果的SQL语句,如SELECT,SHOW等
  263. function Execute($id="me", $sql='')
  264. {
  265. global $dsqli;
  266. if(!$dsqli->isInit)
  267. {
  268. $this->Init($this->pconnect);
  269. }
  270. if($dsqli->isClose)
  271. {
  272. $this->Open(FALSE);
  273. $dsqli->isClose = FALSE;
  274. }
  275. if(!empty($sql))
  276. {
  277. $this->SetQuery($sql);
  278. }
  279. //SQL语句安全检查
  280. if($this->safeCheck)
  281. {
  282. CheckSql($this->queryString);
  283. }
  284. $t1 = ExecTime();
  285. //var_dump($this->queryString);
  286. $this->result[$id] = mysqli_query($this->linkID, $this->queryString);
  287. //var_dump(mysql_error());
  288. //查询性能测试
  289. if($this->recordLog) {
  290. $queryTime = ExecTime() - $t1;
  291. $this->RecordLog($queryTime);
  292. //echo $this->queryString."--{$queryTime}<hr />\r\n";
  293. }
  294. if($this->result[$id]===FALSE)
  295. {
  296. $this->DisplayError(mysqli_error($this->linkID)." <br />Error sql: <font color='red'>".$this->queryString."</font>");
  297. }
  298. }
  299. function Query($id="me",$sql='')
  300. {
  301. $this->Execute($id,$sql);
  302. }
  303. //执行一个SQL语句,返回前一条记录或仅返回一条记录
  304. function GetOne($sql='',$acctype=MYSQLI_ASSOC)
  305. {
  306. global $dsqli;
  307. if(!$dsqli->isInit)
  308. {
  309. $this->Init($this->pconnect);
  310. }
  311. if($dsqli->isClose)
  312. {
  313. $this->Open(FALSE);
  314. $dsqli->isClose = FALSE;
  315. }
  316. if(!empty($sql))
  317. {
  318. if(!preg_match("/LIMIT/i",$sql)) $this->SetQuery(preg_replace("/[,;]$/i", '', trim($sql))." LIMIT 0,1;");
  319. else $this->SetQuery($sql);
  320. }
  321. $this->Execute("one");
  322. $arr = $this->GetArray("one", $acctype);
  323. if(!is_array($arr))
  324. {
  325. return '';
  326. }
  327. else
  328. {
  329. @mysqli_free_result($this->result["one"]); return($arr);
  330. }
  331. }
  332. //执行一个不与任何表名有关的SQL语句,Create等
  333. function ExecuteSafeQuery($sql,$id="me")
  334. {
  335. global $dsqli;
  336. if(!$dsqli->isInit)
  337. {
  338. $this->Init($this->pconnect);
  339. }
  340. if($dsqli->isClose)
  341. {
  342. $this->Open(FALSE);
  343. $dsqli->isClose = FALSE;
  344. }
  345. $this->result[$id] = @mysqli_query($sql,$this->linkID);
  346. }
  347. //返回当前的一条记录并把游标移向下一记录
  348. // MYSQLI_ASSOC、MYSQLI_NUM、MYSQLI_BOTH
  349. function GetArray($id="me",$acctype=MYSQLI_ASSOC)
  350. {
  351. // var_dump($this->result);
  352. if($this->result[$id]===0)
  353. {
  354. return FALSE;
  355. }
  356. else
  357. {
  358. return @mysqli_fetch_array($this->result[$id], $acctype);
  359. }
  360. }
  361. function GetObject($id="me")
  362. {
  363. if($this->result[$id]===0)
  364. {
  365. return FALSE;
  366. }
  367. else
  368. {
  369. return mysqli_fetch_object($this->result[$id]);
  370. }
  371. }
  372. // 检测是否存在某数据表
  373. function IsTable($tbname)
  374. {
  375. global $dsqli;
  376. if(!$dsqli->isInit)
  377. {
  378. $this->Init($this->pconnect);
  379. }
  380. $prefix="#@__";
  381. $tbname = str_replace($prefix, $GLOBALS['cfg_dbprefix'], $tbname);
  382. if( mysqli_num_rows( @mysqli_query($this->linkID, "SHOW TABLES LIKE '".$tbname."'")))
  383. {
  384. return TRUE;
  385. }
  386. return FALSE;
  387. }
  388. //获得MySql的版本号
  389. function GetVersion($isformat=TRUE)
  390. {
  391. global $dsqli;
  392. if(!$dsqli->isInit)
  393. {
  394. $this->Init($this->pconnect);
  395. }
  396. if($dsqli->isClose)
  397. {
  398. $this->Open(FALSE);
  399. $dsqli->isClose = FALSE;
  400. }
  401. $rs = mysqli_query($this->linkID, "SELECT VERSION();");
  402. $row = mysqli_fetch_array($rs);
  403. $mysql_version = $row[0];
  404. mysqli_free_result($rs);
  405. if($isformat)
  406. {
  407. $mysql_versions = explode(".",trim($mysql_version));
  408. $mysql_version = number_format($mysql_versions[0].".".$mysql_versions[1],2);
  409. }
  410. return $mysql_version;
  411. }
  412. //获取特定表的信息
  413. function GetTableFields($tbname, $id="me")
  414. {
  415. global $dsqli;
  416. if(!$dsqli->isInit)
  417. {
  418. $this->Init($this->pconnect);
  419. }
  420. $prefix="#@__";
  421. $tbname = str_replace($prefix, $GLOBALS['cfg_dbprefix'], $tbname);
  422. $query = "SELECT * FROM {$tbname} LIMIT 0,1";
  423. $this->result[$id] = mysqli_query($this->linkID, $query);
  424. }
  425. //获取字段详细信息
  426. function GetFieldObject($id="me")
  427. {
  428. return mysqli_fetch_field($this->result[$id]);
  429. }
  430. //获得查询的总记录数
  431. function GetTotalRow($id="me")
  432. {
  433. if($this->result[$id]===0)
  434. {
  435. return -1;
  436. }
  437. else
  438. {
  439. return @mysqli_num_rows($this->result[$id]);
  440. }
  441. }
  442. //获取上一步INSERT操作产生的ID
  443. function GetLastID()
  444. {
  445. //如果 AUTO_INCREMENT 的列的类型是 BIGINT,则 mysqli_insert_id() 返回的值将不正确。
  446. //可以在 SQL 查询中用 MySQL 内部的 SQL 函数 LAST_INSERT_ID() 来替代。
  447. //$rs = mysqli_query($this->linkID, "Select LAST_INSERT_ID() as lid");
  448. //$row = mysqli_fetch_array($rs);
  449. //return $row["lid"];
  450. return mysqli_insert_id($this->linkID);
  451. }
  452. //释放记录集占用的资源
  453. function FreeResult($id="me")
  454. {
  455. @mysqli_free_result($this->result[$id]);
  456. }
  457. function FreeResultAll()
  458. {
  459. if(!is_array($this->result))
  460. {
  461. return '';
  462. }
  463. foreach($this->result as $kk => $vv)
  464. {
  465. if($vv)
  466. {
  467. @mysqli_free_result($vv);
  468. }
  469. }
  470. }
  471. //设置SQL语句,会自动把SQL语句里的#@__替换为$this->dbPrefix(在配置文件中为$cfg_dbprefix)
  472. function SetQuery($sql)
  473. {
  474. $prefix="#@__";
  475. $sql = str_replace($prefix,$GLOBALS['cfg_dbprefix'],$sql);
  476. $this->queryString = $sql;
  477. }
  478. function SetSql($sql)
  479. {
  480. $this->SetQuery($sql);
  481. }
  482. function RecordLog($runtime=0)
  483. {
  484. $RecordLogFile = dirname(__FILE__).'/../data/mysqli_record_log.inc';
  485. $url = $this->GetCurUrl();
  486. $savemsg = <<<EOT
  487. ------------------------------------------
  488. SQL:{$this->queryString}
  489. Page:$url
  490. Runtime:$runtime
  491. EOT;
  492. $fp = @fopen($RecordLogFile, 'a');
  493. @fwrite($fp, $savemsg);
  494. @fclose($fp);
  495. }
  496. //显示数据链接错误信息
  497. function DisplayError($msg)
  498. {
  499. $errorTrackFile = dirname(__FILE__).'/../data/mysqli_error_trace.inc';
  500. if( file_exists(dirname(__FILE__).'/../data/mysqli_error_trace.php') )
  501. {
  502. @unlink(dirname(__FILE__).'/../data/mysqli_error_trace.php');
  503. }
  504. if($this->showError)
  505. {
  506. $emsg = '';
  507. $emsg .= "<div><h3>DedeCMS Error Warning!</h3>\r\n";
  508. $emsg .= "<div><a href='http://bbs.dedecms.com' target='_blank' style='color:red'>Technical Support: http://bbs.dedecms.com</a></div>";
  509. $emsg .= "<div style='line-helght:160%;font-size:14px;color:green'>\r\n";
  510. $emsg .= "<div style='color:blue'><br />Error page: <font color='red'>".$this->GetCurUrl()."</font></div>\r\n";
  511. $emsg .= "<div>Error infos: {$msg}</div>\r\n";
  512. $emsg .= "<br /></div></div>\r\n";
  513. echo $emsg;
  514. }
  515. $savemsg = 'Page: '.$this->GetCurUrl()."\r\nError: ".$msg."\r\nTime".date('Y-m-d H:i:s');
  516. //保存MySql错误日志
  517. $fp = @fopen($errorTrackFile, 'a');
  518. @fwrite($fp, '<'.'?php exit();'."\r\n/*\r\n{$savemsg}\r\n*/\r\n?".">\r\n");
  519. @fclose($fp);
  520. }
  521. //获得当前的脚本网址
  522. function GetCurUrl()
  523. {
  524. if(!empty($_SERVER["REQUEST_URI"]))
  525. {
  526. $scriptName = $_SERVER["REQUEST_URI"];
  527. $nowurl = $scriptName;
  528. }
  529. else
  530. {
  531. $scriptName = $_SERVER["PHP_SELF"];
  532. if(empty($_SERVER["QUERY_STRING"])) {
  533. $nowurl = $scriptName;
  534. }
  535. else {
  536. $nowurl = $scriptName."?".$_SERVER["QUERY_STRING"];
  537. }
  538. }
  539. return $nowurl;
  540. }
  541. }
  542. //复制一个对象副本
  543. function CopySQLiPoint(&$ndsql)
  544. {
  545. $GLOBALS['dsqli'] = $ndsql;
  546. }
  547. //SQL语句过滤程序,由80sec提供,这里作了适当的修改
  548. if (!function_exists('CheckSql'))
  549. {
  550. function CheckSql($db_string,$querytype='select')
  551. {
  552. global $cfg_cookie_encode;
  553. $clean = '';
  554. $error='';
  555. $old_pos = 0;
  556. $pos = -1;
  557. $log_file = DEDEINC.'/../data/'.md5($cfg_cookie_encode).'_safe.txt';
  558. $userIP = GetIP();
  559. $getUrl = GetCurUrl();
  560. //如果是普通查询语句,直接过滤一些特殊语法
  561. if($querytype=='select')
  562. {
  563. $notallow1 = "[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}";
  564. //$notallow2 = "--|/\*";
  565. if(preg_match("/".$notallow1."/i", $db_string))
  566. {
  567. fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||SelectBreak\r\n");
  568. exit("<font size='5' color='red'>Safe Alert: Request Error step 1 !</font>");
  569. }
  570. }
  571. //完整的SQL检查
  572. while (TRUE)
  573. {
  574. $pos = strpos($db_string, '\'', $pos + 1);
  575. if ($pos === FALSE)
  576. {
  577. break;
  578. }
  579. $clean .= substr($db_string, $old_pos, $pos - $old_pos);
  580. while (TRUE)
  581. {
  582. $pos1 = strpos($db_string, '\'', $pos + 1);
  583. $pos2 = strpos($db_string, '\\', $pos + 1);
  584. if ($pos1 === FALSE)
  585. {
  586. break;
  587. }
  588. elseif ($pos2 == FALSE || $pos2 > $pos1)
  589. {
  590. $pos = $pos1;
  591. break;
  592. }
  593. $pos = $pos2 + 1;
  594. }
  595. $clean .= '$s$';
  596. $old_pos = $pos + 1;
  597. }
  598. $clean .= substr($db_string, $old_pos);
  599. $clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean)));
  600. if (strpos($clean, '@') !== FALSE OR strpos($clean,'char(')!== FALSE OR strpos($clean,'"')!== FALSE
  601. OR strpos($clean,'$s$$s$')!== FALSE)
  602. {
  603. $fail = TRUE;
  604. if(preg_match("#^create table#i",$clean)) $fail = FALSE;
  605. $error="unusual character";
  606. }
  607. //老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它
  608. if (strpos($clean, 'union') !== FALSE && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0)
  609. {
  610. $fail = TRUE;
  611. $error="union detect";
  612. }
  613. //发布版本的程序可能比较少包括--,#这样的注释,但是黑客经常使用它们
  614. elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== FALSE || strpos($clean, '#') !== FALSE)
  615. {
  616. $fail = TRUE;
  617. $error="comment detect";
  618. }
  619. //这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库
  620. elseif (strpos($clean, 'sleep') !== FALSE && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0)
  621. {
  622. $fail = TRUE;
  623. $error="slown down detect";
  624. }
  625. elseif (strpos($clean, 'benchmark') !== FALSE && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0)
  626. {
  627. $fail = TRUE;
  628. $error="slown down detect";
  629. }
  630. elseif (strpos($clean, 'load_file') !== FALSE && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0)
  631. {
  632. $fail = TRUE;
  633. $error="file fun detect";
  634. }
  635. elseif (strpos($clean, 'into outfile') !== FALSE && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0)
  636. {
  637. $fail = TRUE;
  638. $error="file fun detect";
  639. }
  640. //老版本的MYSQL不支持子查询,我们的程序里可能也用得少,但是黑客可以使用它来查询数据库敏感信息
  641. elseif (preg_match('~\([^)]*?select~s', $clean) != 0)
  642. {
  643. $fail = TRUE;
  644. $error="sub select detect";
  645. }
  646. if (!empty($fail))
  647. {
  648. fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||$error\r\n");
  649. exit("<font size='5' color='red'>Safe Alert: Request Error step 2!</font>");
  650. }
  651. else
  652. {
  653. return $db_string;
  654. }
  655. }
  656. }