PHP PDO数据库类

<?php
//<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
/**
 * SQL字符串 适用于DB类中的SQL文本 
 * Enter description here ...
 * @author wj008
 *
 */

class SqlText {
	var $text;
	function SqlText($Str) {
		$this->text = $Str;
	}
 }
 /**
  * 数据库操作类
  * Enter description here ...
  * @author wj008
  *
  */
class DataBase {
	var $PdoDb = NULL;
	var $IsXSS = false; //是否清除危险脚本
	private $Fdbtype, $Fhost, $Fport, $Fdbname, $Fuser, $Fpwd, $Fopt, $Fpf;
	/**
	 * 数据库操作类入口
	 * @param string $dbtype mysql或者sqlite
	 * @param string $host 如果是MYSQL数据库 需要填写 IP如 127.0.0.1 如果是SQLITE 请填写绝对路径
	 * @param string $port MYSQL选项 端口号 SQLITE不需要填写
	 * @param string $dbname MYSQL选项 数据库名称
	 * @param string $user MYSQL选项 用户名
	 * @param string $pwd MYSQL选项 连接密码
	 * @param array $opt MYSQL选项 连接选项
	 * @param string $pf 前缀名称
	 */
	function __construct($dbtype = 'mysql', $host = '127.0.0.1', $port = '', $dbname = '', $user = '', $pwd = '', $opt = array(), $pf = '') {
		$this->Fdbtype = $dbtype;
		$this->Fhost = $host;
		$this->Fport = $port;
		$this->Fdbname = $dbname;
		$this->Fuser = $user;
		$this->Fpwd = $pwd;
		$this->Fopt = $opt;
		$this->Fpf = $pf;
	}
    /**
     * 打开数据库连接
     */
	
	public function open($isclean=false) {
		if ($this->PdoDb == NULL) {
			if ($this->Fdbtype == 'mysql') {
				$dns = 'mysql:host=' . $this->Fhost . (($this->Fport != '') ? (';port=' . $this->Fport) : '') . ';dbname=' . $this->Fdbname;
				$this->PdoDb = new PDO ( $dns, $this->Fuser, $this->Fpwd, $this->Fopt );
				$this->PdoDb->exec ( 'SET NAMES \'utf8\';' );
			} else if ($this->Fdbtype == 'sqlite') {
				$dns = 'sqlite:' . $this->Fhost;
				$this->PdoDb = new PDO ( $dns );
			}
		}
		$this->IsXSS=$isclean;
	}
	private function test($sql,$arr=array())
	{
		$sql = str_replace ( '@pf_', $this->Fpf, $sql );
		for($i=0,$len=count($arr);$i<$len;$i++){
		$pos = strpos($sql, '?');
		if($pos===false)break;
		if(gettype($arr[$i])=='string')
		$temp='\''.addcslashes ($arr[$i], '\'\\' ).'\'';
		else $temp=$arr[$i];
        $sql=substr_replace($sql,$temp,$pos,1);
		}
		return ($sql);
	}
	/**
	 * 判断是否打开数据库连接
	 * @return boolean
	 */
	private function getfield($tb)
	{
		$tb = str_replace ( '@pf_', $this->Fpf, $tb );
		if($this->Fdbtype=='sqlite')
		{
			$Row=$this->getone('select sql from sqlite_master where [name]=? and [type]=\'table\'',array($tb));
			$sql=$Row['sql'];
			preg_match_all('/\n\"(\w*)\"\s/i',$sql,$zdarrs);
			return $zdarrs[1];
		}
		else
		{
			$Row=$this->getone('show create table `'.$tb.'`;');
			$sql=$Row['Create Table'];
			preg_match_all('/\n\s*`(\w*)`\s/i',$sql,$zdarrs);
			return $zdarrs[1];
		}
		
	}
	/**
	 * 判断是否打开数据库
	 * @return boolean 真是打开
	 */
	public function isopen() {
		return $this->PdoDb != NULL;
	}
	/**
	 * 关闭数据库
	 */
	public function close() {
		$this->PdoDb = NULL;
	}
	/**
	 * 执行sql代码
	 * @param string $sql
	 */
	public function beginTransaction(){if ($this->PdoDb == NULL)die ( '未打开数据库就进行数据查询操作!' );$this->PdoDb->beginTransaction();}
	public function commit(){if ($this->PdoDb == NULL)die ( '未打开数据库就进行数据查询操作!' );$this->PdoDb->commit();}
	public function rollBack(){if ($this->PdoDb == NULL)die ( '未打开数据库就进行数据查询操作!' );$this->PdoDb->rollBack();}
 
	public function exec($sql) {
		if ($this->PdoDb == NULL)die ( '未打开数据库就进行数据查询操作!' );
		if ($this->Fpf != '')
			$sql = str_replace ( '@pf_', $this->Fpf, $sql );
		$this->PdoDb->exec ( $sql );
	}
	/**
	 * 获取最后插入的ID
	 * @param string $name 获取字段名称
	 */
	public function lastId($name = NULL) {
		if ($this->PdoDb == NULL)
			die ( '未打开数据库就进行数据查询操作!' );
		return $this->PdoDb->lastInsertId ( $name );
	}
	/**
	 * 执行SQL语句 
	 * @param string $sql
	 * @param array $args
	 */
	public function execute($sql, $args = array()) {
		if ($this->Fpf != '')
		$sql = str_replace ( '@pf_', $this->Fpf, $sql );
		if ($this->PdoDb == NULL)die ( '未打开数据库就进行数据查询操作!' );
		try
		{
			$Stm = $this->PdoDb->prepare ( $sql );
			if(!$Stm->execute ( $args ))throw new Exception('错误信息:执行语句错误'.$this->test($sql,$args)); 
		}
		catch (PDOException  $e) {
		throw new Exception('错误信息:'.$e->getMessage().',SQL:'.$this->test($sql,$args)); 
	    }
		return $Stm;
	}	
	public function getdata($sql, $args = array(),$type=PDO::FETCH_ASSOC) {
		$Stm=$this->execute ( $sql, $args );
		$rows=$Stm->fetchAll ($type);
		$Stm->closeCursor();
		return $rows;
	}
	public function getone($sql, $args = array(),$type=PDO::FETCH_ASSOC) {
		
		$A = $this->getdata( $sql, $args,$type);
		if (count ( $A ) > 0)return $A [0];
		else return NULL;
	}

	public function insert($tb, $vals) {
		$fields=$this->getfield($tb);
		$SqlKey = array ();
		$SqlPam = array ();
		$SqlVal = array ();
		foreach ( $vals as $key => $value ) {
			if(!in_array($key,$fields)||$key=='id')continue;
			$SqlKey [] = '`' . $key . '`';
			if ($value === NULL) {
				$SqlPam [] = 'NULL';
			} else if (gettype ( $value ) == 'object' && get_class ( $value ) == 'SqlText') {
				$SqlPam [] = $value->text;
			} else {
				$SqlPam [] = '?';
				if (gettype ( $value ) == 'string' && $this->IsXSS)
					$SqlVal [] = $this->RemoveXSS ( $value );
				else
					$SqlVal [] = $value;
			}
		}
		$sql = 'insert into ' . $tb . '(' . join ( ',', $SqlKey ) . ') values (' . join ( ',', $SqlPam ) . ')';
		$this->execute ( $sql, $SqlVal );
	}
	//不执行没有条件的数据 以避免错误删除数据
	private function Pupdate($tb, $vals, $where, $args = array()) {
		
		$fields=$this->getfield($tb);
		
		$SqlPam = array ();
		$SqlVal = array ();
		foreach ( $vals as $key => $value ) {
			if(!in_array($key,$fields)||$key=='id')continue;
			if ($value === NULL) {
				$SqlPam [] = '`' . $key . '`=NULL';
			} else if (gettype ( $value ) == 'object' && get_class ( $value ) == 'SqlText') {
				$SqlPam [] = '`' . $key . '`=' . $value->text;
			} else {
				$SqlPam [] = '`' . $key . '`=?';
				if (gettype ( $value ) == 'string' && $this->IsXSS)
					$SqlVal [] = $this->RemoveXSS ( $value );
				else
					$SqlVal [] = $value;
			}
		}
		$where = trim ( $where );
		if (strrpos ( $where, 'where' ) !== false && strrpos ( $where, 'where' ) == 0)
			$where = trim ( substr ( $where, 5 ) );
		$sql = 'update ' . $tb . ' set ' . join ( ',', $SqlPam ) . ' where ' . $where;
		
		
		if (count ( $args ) > 0)
			for($i = 0; $i < count ( $args ); $i ++)
				$SqlVal [] = $args [$i];
		$this->execute ( $sql, $SqlVal );
	}
	public function update($tb, $vals, $wha = NULL, $whb = NULL) {
		
		if (gettype ( $wha ) == 'integer' || (gettype ( $wha ) == 'string' && is_numeric ( trim ( $wha ) ))) {
			if ($whb === NULL) {
				$this->Pupdate ( $tb, $vals, 'id=?', array (intval ( trim ( $wha ) ) ) );
			}
		} else if (gettype ( $wha ) == 'string' && ! is_numeric ( trim ( $wha ) )) {
			$this->Pupdate ( $tb, $vals, $wha, $whb );
			if (gettype ( $whb ) == 'array')
				$this->Pupdate ( $tb,$vals, $wha, $whb );
			else
				$this->Pupdate ( $tb, $vals,$wha );
		}
	}
	//不执行没有条件的数据 以避免错误删除数据
	private function Pdelete($tb, $where, $args = array()) {
		$where = trim ( $where );
		if (strrpos ( $where, 'where' ) !== false && strrpos ( $where, 'where' ) == 0)
			$where = trim ( substr ( $where, 5 ) );
		$sql = 'delete from ' . $tb . ' where ' . $where;
		//die($sql);
		$this->execute ( $sql, $args );
	}
	public function delete($tb, $wha = NULL, $whb = NULL) {
		if (gettype ( $wha ) == 'integer' || (gettype ( $wha ) == 'string' && is_numeric ( trim ( $wha ) ))) {
			if ($whb === NULL) {
				$this->Pdelete ( $tb, 'id=?', array (intval ( trim ( $wha ) ) ) );
			}
		} else if (gettype ( $wha ) == 'string' && ! is_numeric ( trim ( $wha ) )) {
			if (gettype ( $whb ) == 'array')
				$this->Pdelete ( $tb, $wha, $whb );
			else
				$this->Pdelete ( $tb, $wha );
		}
	}
	//过滤危险脚本但保留一定的标签================================
	public function RemoveXSS($val) {
		if (strpos ( $val, '<' ) === false)
			return $val;	
		$val = preg_replace ( '/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val );
		$search = 'abcdefghijklmnopqrstuvwxyz';
		$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
		$search .= '1234567890!@#$%^&*()';
		$search .= '~`";:?+/={}[]-_|\'\\';
		for($i = 0; $i < strlen ( $search ); $i ++) {
			$val = preg_replace ( '/(&#[x|X]0{0,8}' . dechex ( ord ( $search [$i] ) ) . ';?)/i', $search [$i], $val ); // with a ;     
			$val = preg_replace ( '/(�{0,8}' . ord ( $search [$i] ) . ';?)/', $search [$i], $val ); // with a ;    
		}
		$ra1 = array ('javascript', 'vbscript', 'expression', 'applet' );
		$ra2 = array ('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload' );
		$ra = array_merge ( $ra1, $ra2 );
		$val = preg_replace ( "'<script[^>]*?>.*?</script>'si", "", $val );
		$val = preg_replace ( "'<style[^>]*?>.*?</style>'si", "", $val );
		$val = preg_replace ( "/<(script|iframe|expression|applet|meta|xml|blink|style|frame|frameset|ilayer|layer|bgsound|title|base|link)(|[^>]+)>/i", "", $val );
		$val = preg_replace ( "/<\\/(script|iframe|expression|applet|meta|xml|blink|style|frame|frameset|ilayer|layer|bgsound|title|base)>/i", "", $val );
		$newval = "";
		$idx = 0;
		$edx = 0;
		do {
			$idx = strpos ( $val, '<', $edx );
			if ($idx !== false) {
				if ($idx > $edx) {
					$str = substr ( $val, $edx, $idx - $edx );
					$newval .= $str ;
				}
				$edx = strpos ( $val, '>', $idx );
				if ($edx !== false && $edx > $idx) {
					$edx ++;
					$tag = substr ( $val, $idx, $edx - $idx );
					
					$ridx = strrpos ( $tag, '<', 1 );
					if ($ridx !== false) {
						$str = substr ( $val, $idx, $ridx );
						$newval .=  $str ;
						$idx = $idx + $ridx;
						$tag = substr ( $val, $idx, $edx - $idx );
					}
				     for($j = 0; $j < count ( $ra1 ); $j ++) {
							if (stripos ( $tag, $ra1 [$j] ) !== false) {
								$tag = str_ireplace ( $ra1 [$j].':', '#', $tag );
							}
					 }
					if (stripos ( $tag, 'on' ) === false) {
						$newval .= $tag;
					} 
					else {
						for($j = 0; $j < count ( $ra2 ); $j ++) {
							if (stripos ( $tag, $ra2 [$j] ) !== false) {
								$tag = preg_replace ( '/' . $ra2 [$j] . '="[^"]+"/i', "", $tag );
								$tag = preg_replace ( "/" . $ra2 [$j] . "='[^']+'/i", "", $tag );
								$tag = preg_replace ( "/" . $ra2 [$j] . "=[^ ]+>/i", ">", $tag );
								$tag = preg_replace ( "/" . $ra2 [$j] . "=[^ ]+ /i", "", $tag );
								$tag = str_ireplace ( $ra2 [$j], "", $tag );
							}
						}
						$newval .= $tag;
					}
				} else {
					$str = substr ( $val, $idx );
					$newval .=  $str ;
				}
			} else {
				$str = substr ( $val, $edx );
				$newval .= $str ;
			}
		} while ( $idx !== false && $edx !== false );
		return $newval;
	}
}
	
function _sql($str) {
	return new SqlText ( $str );
}

?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值