PDO2
来源:互联网 发布:阿里云邮箱 ssl端口 编辑:程序博客网 时间:2024/06/02 06:47
以前由于兼容性的问题,一直只封装了mysql和mysqli,没有封装pdo,不过我想现在已经没有必要死拖着php4不放了,应该彻底面对PHP5及其后版本。
优点:
1.效率更高
类似于adodb,phplib等库,pdo支持多种数据库,也就是说如果不使用mysql做为数据库程序也不需要进行什么更改,仅仅改一个参数就行了,由于pdo对多数据库操作的封装是用C实现的,因此比adodb等PHP实现方式效率更高,并且以后的php6版本也不再支
持mysql系列函数。
在连续执行相同结构的sql时,可以先预备好结构,最后一次性执行,这样也会提升效率。
2.更安全
输入sql使用占位符的方式,基本消除sql注入现象发生。当然以前的方式过滤得当也同样安全。
为了不修改程序,封装了PDO的操作。
PHP代码
<?php /** * 虽然尽量照顾到mysql和mysqli的兼容性,没有使用占位符模式,不过最近加入的新办法仍有可能没加入mysql,mysqli中 * */ class db extends PDO { var $count; //记录执行语句数. var $sql; //记录全部sql和运行间隔 var $startTime; //开始时间,基本上整个页面的开始时间与db类开始运行时的时间很接近,误差在0.005秒左右,要求不严格情况下可以当作页面开始时间 var $runTime; //记录上次运行时间 /** * 用pdo连接mysql */ public function __construct($user, $pass, $dbname, $host=“localhost”, $charset = “utf8″, $options = array(PDO::ATTR_PERSISTENT => true)) { try{ parent::__construct(“mysql:host=”.$host.“;dbname=”.$dbname, $user, $pass, $options); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); //异常处理:也可以使用PDO默认的异常处理ERRMODE_EXCEPTION $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); //fetch模式,关联数组 $this->query(“SET NAMES ’$charset’”); //连接字符集 if(DEBUG){ $this->startTime = microtime(); $this->runTime = $this->startTime; } }catch (PDOException $e){ die(‘无法连接mysql,请检查参数’); } } /** * 取得所有数据,返回二维数组,可使用占位符 * @example getAll(”select * from test”) * @return array */ public function getAll($sql) { $rs = $this->prepare($sql); $params = func_get_args(); $paramsCnt = count($params); for ($i=1; $i<$paramsCnt; $i++) { $rs->bindParam($i, $params[$i]); } $rs->execute(); $all = $rs->fetchAll(); if(DEBUG) self::debug($sql); unset($rs); return $all; } /** * 取单行记录,可以用传统sql语句方式,或者占位符方式,可以有任意多个占位符 * @example getRow(”select * from test where id = 11″) * @example getRow(”select * from test where id > ? and gender = ?”, $id, 1); * @return 一维数组 */ public function getOne($sql) { $rs = $this->prepare($sql); $params = func_get_args(); $paramsCnt = count($params); for ($i=1; $i<$paramsCnt; $i++) { $rs->bindParam($i, $params[$i]); } $rs->execute(); $row = $rs->fetch(); if(DEBUG) self::debug($sql); unset($rs); return $row; } /** * 取第一条记录第一个字段的值,用于只需要取一个字段的情况,也可用于复杂的统计记录数 * @example getOne(”select count(*) from test”); //统计记录数 * @example getOne(”select count(*) from test where username=? and grade=?”, $username, $grade); */ public function getField($sql) { $rs = $this->prepare($sql); $params = func_get_args(); $paramsCnt = count($params); for ($i=1; $i<$paramsCnt; $i++) { $rs->bindParam($i, $params[$i]); } $rs->execute(); $value = $rs->fetchColumn(); if(DEBUG) self::debug($sql); unset($rs); return $value; } /** * 扩展PDO::exec(),增加占位符功能 * @param string $sql * @param int|bool 失败返回false.update和delete成功返回影响的行数,insert返回插入的id */ public function exec($sql) { $rs = $this->prepare($sql); $params = func_get_args(); $paramsCnt = count($params); for ($i=1; $i<$paramsCnt; $i++) { $rs->bindParam($i, $params[$i]); } $retval = $rs->execute(); if ($retval === false) return false; if(strpos(strtolower($sql), ‘insert’) !==false) { return $this->lastInsertId(); } if(DEBUG) self::debug($sql); return $rs->rowCount(); } /** * 计算符合条件的记录总数.如果语句较复杂,可以用getField达到同样效果 * @param str $table 表名 * @param str $condition 记录必须符合的条件.如”id > 100″ * @return int 总数 * 例: $num = $db->dbCount(’t_person’); * $num = $db->dbCount(’t_person’, ’p_id > 100′, ’p_id’); */ function dbCount($table, $condition = ”, $field=‘*’) { if($condition != ”) { if(strtoupper(substr(trim($condition),0,5)) != ‘WHERE’) $condition = “WHERE $condition”; } $sql = “SELECT COUNT($field) FROM `$table` $condition”; //这里不统计sql语句,因为在getField方法里统计了 return $this->getField($sql); } /** * 常用于分页中,取记录集时要limit,但统计总数又得忽略limit,郁闷啊,以前老是要另写一句统计总数.呵呵,现在爽了 * 用法: * $rs = $db->getAll(”SELECT SQL_CALC_FOUND_ROWS * FROM t_person LIMIT ?, ?”, $start, $end); * $total = $db->foundRows(); */ public function foundRows() { $rs = $this->query(‘SELECT found_rows()’); return $rs->fetchColumn(); }
//取最大值 function getMax($table, $field, $condition=”){ if(!emptyempty($condition)) $condition = ‘WHERE ’.$condition; $sql = “SELECT max(`”.$field.“`) FROM `$table` $condition”; return $this->getField($sql); } //取最小值 function getMin($table, $field, $condition=”){ if(!emptyempty($condition)) $condition = ‘WHERE ’.$condition; $sql = “SELECT min(`”.$field.“`) FROM `$table` $condition”; $this->getField($sql); } }