123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- <?php
- /**
- * db_mysqli.class.php MYSQLI数据库实现类
- *
- * @copyright (C) 2005-2015 PHPCMS
- * @license http://www.phpcms.cn/license/
- * @lastmodify 2016-02-01
- */
- final class db_mysqli {
-
- /**
- * 数据库配置信息
- */
- private $config = null;
-
- /**
- * 数据库连接资源句柄
- */
- public $link = null;
-
- /**
- * 最近一次查询资源句柄
- */
- public $lastqueryid = null;
-
- /**
- * 统计数据库查询次数
- */
- public $querycount = 0;
-
- public function __construct() {
- }
-
- /**
- * 打开数据库连接,有可能不真实连接数据库
- * @param $config 数据库连接参数
- *
- * @return void
- */
- public function open($config) {
- $this->config = $config;
- if($config['autoconnect'] == 1) {
- $this->connect();
- }
- }
- /**
- * 真正开启数据库连接
- *
- * @return void
- */
- public function connect() {
- $this->link = new mysqli($this->config['hostname'], $this->config['username'], $this->config['password'], $this->config['database'], $this->config['port']?intval($this->config['port']):3306);
- if(mysqli_connect_error()){
- $this->halt('Can not connect to MySQL server');
- return false;
- }
- if($this->version() > '4.1') {
- $charset = isset($this->config['charset']) ? $this->config['charset'] : '';
- $serverset = $charset ? "character_set_connection='$charset',character_set_results='$charset',character_set_client=binary" : '';
- $serverset .= $this->version() > '5.0.1' ? ((empty($serverset) ? '' : ',')." sql_mode='' ") : '';
- $serverset && $this->link->query("SET $serverset");
- }
- return $this->link;
- }
- /**
- * 数据库查询执行方法
- * @param $sql 要执行的sql语句
- * @return 查询资源句柄
- */
- private function execute($sql) {
- if(!is_object($this->link)) {
- $this->connect();
- }
- $this->lastqueryid = $this->link->query($sql) or $this->halt($this->link->error, $sql);
- $this->querycount++;
- return $this->lastqueryid;
- }
- /**
- * 执行sql查询
- * @param $data 需要查询的字段值[例`name`,`gender`,`birthday`]
- * @param $table 数据表
- * @param $where 查询条件[例`name`='$name']
- * @param $limit 返回结果范围[例:10或10,10 默认为空]
- * @param $order 排序方式 [默认按数据库默认方式排序]
- * @param $group 分组方式 [默认为空]
- * @param $key 返回数组按键名排序
- * @return array 查询结果集数组
- */
- public function select($data, $table, $where = '', $limit = '', $order = '', $group = '', $key = '') {
- $where = $where == '' ? '' : ' WHERE '.$where;
- $order = $order == '' ? '' : ' ORDER BY '.$order;
- $group = $group == '' ? '' : ' GROUP BY '.$group;
- $limit = $limit == '' ? '' : ' LIMIT '.$limit;
- $field = explode(',', $data);
- array_walk($field, array($this, 'add_special_char'));
- $data = implode(',', $field);
- $sql = 'SELECT '.$data.' FROM `'.$this->config['database'].'`.`'.$table.'`'.$where.$group.$order.$limit;
- $this->execute($sql);
- if(!is_object($this->lastqueryid)) {
- return $this->lastqueryid;
- }
- $datalist = array();
- while(($rs = $this->fetch_next()) != false) {
- if($key) {
- $datalist[$rs[$key]] = $rs;
- } else {
- $datalist[] = $rs;
- }
- }
- $this->free_result();
- return $datalist;
- }
- /**
- * 获取单条记录查询
- * @param $data 需要查询的字段值[例`name`,`gender`,`birthday`]
- * @param $table 数据表
- * @param $where 查询条件
- * @param $order 排序方式 [默认按数据库默认方式排序]
- * @param $group 分组方式 [默认为空]
- * @return array/null 数据查询结果集,如果不存在,则返回空
- */
- public function get_one($data, $table, $where = '', $order = '', $group = '') {
- $where = $where == '' ? '' : ' WHERE '.$where;
- $order = $order == '' ? '' : ' ORDER BY '.$order;
- $group = $group == '' ? '' : ' GROUP BY '.$group;
- $limit = ' LIMIT 1';
- $field = explode( ',', $data);
- array_walk($field, array($this, 'add_special_char'));
- $data = implode(',', $field);
- $sql = 'SELECT '.$data.' FROM `'.$this->config['database'].'`.`'.$table.'`'.$where.$group.$order.$limit;
- $this->execute($sql);
- $res = $this->fetch_next();
- $this->free_result();
- return $res;
- }
-
- /**
- * 遍历查询结果集
- * @param $type 返回结果集类型
- * MYSQLI_ASSOC, MYSQLI_NUM, or MYSQLI_BOTH
- * @return array
- */
- public function fetch_next($type=MYSQLI_ASSOC) {
- $res = $this->lastqueryid->fetch_array($type);
- if(!$res) {
- $this->free_result();
- }
- return $res;
- }
-
- /**
- * 释放查询资源
- * @return void
- */
- public function free_result() {
- if(is_resource($this->lastqueryid)) {
- $this->lastqueryid->free();
- $this->lastqueryid = null;
- }
- }
-
- /**
- * 直接执行sql查询
- * @param $sql 查询sql语句
- * @return boolean/query resource 如果为查询语句,返回资源句柄,否则返回true/false
- */
- public function query($sql) {
- return $this->execute($sql);
- }
-
- /**
- * 执行添加记录操作
- * @param $data 要增加的数据,参数为数组。数组key为字段值,数组值为数据取值
- * @param $table 数据表
- * @return boolean
- */
- public function insert($data, $table, $return_insert_id = false, $replace = false) {
- if(!is_array( $data ) || $table == '' || count($data) == 0) {
- return false;
- }
-
- $fielddata = array_keys($data);
- $valuedata = array_values($data);
- array_walk($fielddata, array($this, 'add_special_char'));
- array_walk($valuedata, array($this, 'escape_string'));
-
- $field = implode (',', $fielddata);
- $value = implode (',', $valuedata);
- $cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';
- $sql = $cmd.' `'.$this->config['database'].'`.`'.$table.'`('.$field.') VALUES ('.$value.')';
- $return = $this->execute($sql);
- return $return_insert_id ? $this->insert_id() : $return;
- }
-
- /**
- * 获取最后一次添加记录的主键号
- * @return int
- */
- public function insert_id() {
- if(!is_object($this->link)) {
- $this->connect();
- }
- return $this->link->insert_id;
- }
-
- /**
- * 执行更新记录操作
- * @param $data 要更新的数据内容,参数可以为数组也可以为字符串,建议数组。
- * 为数组时数组key为字段值,数组值为数据取值
- * 为字符串时[例:`name`='phpcms',`hits`=`hits`+1]。
- * 为数组时[例: array('name'=>'phpcms','password'=>'123456')]
- * 数组可使用array('name'=>'+=1', 'base'=>'-=1');程序会自动解析为`name` = `name` + 1, `base` = `base` - 1
- * @param $table 数据表
- * @param $where 更新数据时的条件
- * @return boolean
- */
- public function update($data, $table, $where = '') {
- if($table == '' or $where == '') {
- return false;
- }
- $where = ' WHERE '.$where;
- $field = '';
- if(is_string($data) && $data != '') {
- $field = $data;
- } elseif (is_array($data) && count($data) > 0) {
- $fields = array();
- foreach($data as $k=>$v) {
- switch (substr($v, 0, 2)) {
- case '+=':
- $v = substr($v,2);
- if (is_numeric($v)) {
- $fields[] = $this->add_special_char($k).'='.$this->add_special_char($k).'+'.$this->escape_string($v, '', false);
- } else {
- continue;
- }
-
- break;
- case '-=':
- $v = substr($v,2);
- if (is_numeric($v)) {
- $fields[] = $this->add_special_char($k).'='.$this->add_special_char($k).'-'.$this->escape_string($v, '', false);
- } else {
- continue;
- }
- break;
- default:
- $fields[] = $this->add_special_char($k).'='.$this->escape_string($v);
- }
- }
- $field = implode(',', $fields);
- } else {
- return false;
- }
- $sql = 'UPDATE `'.$this->config['database'].'`.`'.$table.'` SET '.$field.$where;
- return $this->execute($sql);
- }
-
- /**
- * 执行删除记录操作
- * @param $table 数据表
- * @param $where 删除数据条件,不充许为空。
- * 如果要清空表,使用empty方法
- * @return boolean
- */
- public function delete($table, $where) {
- if ($table == '' || $where == '') {
- return false;
- }
- $where = ' WHERE '.$where;
- $sql = 'DELETE FROM `'.$this->config['database'].'`.`'.$table.'`'.$where;
- return $this->execute($sql);
- }
-
- /**
- * 获取最后数据库操作影响到的条数
- * @return int
- */
- public function affected_rows() {
- if(!is_object($this->link)) {
- $this->connect();
- }
- return $this->link->affected_rows;
- }
-
- /**
- * 获取数据表主键
- * @param $table 数据表
- * @return array
- */
- public function get_primary($table) {
- $this->execute("SHOW COLUMNS FROM $table");
- while($r = $this->fetch_next()) {
- if($r['Key'] == 'PRI') break;
- }
- return $r['Field'];
- }
- /**
- * 获取表字段
- * @param $table 数据表
- * @return array
- */
- public function get_fields($table) {
- $fields = array();
- $this->execute("SHOW COLUMNS FROM $table");
- while($r = $this->fetch_next()) {
- $fields[$r['Field']] = $r['Type'];
- }
- return $fields;
- }
- /**
- * 检查不存在的字段
- * @param $table 表名
- * @return array
- */
- public function check_fields($table, $array) {
- $fields = $this->get_fields($table);
- $nofields = array();
- foreach($array as $v) {
- if(!array_key_exists($v, $fields)) {
- $nofields[] = $v;
- }
- }
- return $nofields;
- }
- /**
- * 检查表是否存在
- * @param $table 表名
- * @return boolean
- */
- public function table_exists($table) {
- $tables = $this->list_tables();
- return in_array($table, $tables) ? 1 : 0;
- }
-
- public function list_tables() {
- $tables = array();
- $this->execute("SHOW TABLES");
- while($r = $this->fetch_next()) {
- $tables[] = $r['Tables_in_'.$this->config['database']];
- }
- return $tables;
- }
- /**
- * 检查字段是否存在
- * @param $table 表名
- * @return boolean
- */
- public function field_exists($table, $field) {
- $fields = $this->get_fields($table);
- return array_key_exists($field, $fields);
- }
- public function num_rows($sql) {
- $this->lastqueryid = $this->execute($sql);
- return $this->lastqueryid ? $this->lastqueryid->num_rows : 0;
- }
- public function num_fields($sql) {
- $this->lastqueryid = $this->execute($sql);
- return $this->lastqueryid ? $this->lastqueryid->field_count : null;
- }
- public function result($sql, $row) {
- $this->lastqueryid = $this->execute($sql);
- $this->lastqueryid->data_seek($row);
- $assocs = $this->lastqueryid->fetch_row();
- return $assocs[0];
- }
- public function error() {
- if(!is_object($this->link)) {
- $this->connect();
- }
- return $this->link->error;
- }
- public function errno() {
- if(!is_object($this->link)) {
- $this->connect();
- }
- return intval($this->link->errno);
- }
- public function version() {
- if(!is_object($this->link)) {
- $this->connect();
- }
- return $this->link->server_info;//server_version
- }
- public function close() {
- if ($this->link) {
- $this->link->close();
- }
- $this->link = null;
- }
- public function escape($str){
- if(!is_object($this->link)) {
- $this->connect();
- }
- return $this->link->real_escape_string($str);
- }
- public function halt($message = '', $sql = '') {
- if($this->config['debug']) {
- $this->errormsg = "<b>MySQL Query : </b> $sql <br /><b> MySQL Error : </b>".$this->error()." <br /> <b>MySQL Errno : </b>".$this->errno()." <br /><b> Message : </b> $message <br /><a href='http://faq.phpcms.cn/?errno=".$this->errno()."&msg=".urlencode($this->error())."' target='_blank' style='color:red'>Need Help?</a>";
- $msg = $this->errormsg;
- echo '<div style="font-size:12px;text-align:left; border:1px solid #9cc9e0; padding:1px 4px;color:#000000;font-family:Arial, Helvetica,sans-serif;"><span>'.$msg.'</span></div>';
- exit;
- } else {
- return false;
- }
- }
- /**
- * 对字段两边加反引号,以保证数据库安全
- * @param $value 数组值
- */
- public function add_special_char(&$value) {
- if('*' == $value || false !== strpos($value, '(') || false !== strpos($value, '.') || false !== strpos ( $value, '`')) {
- //不处理包含* 或者 使用了sql方法。
- } else {
- $value = '`'.trim($value).'`';
- }
- if (preg_match("/\b(select|insert|update|delete)\b/i", $value)) {
- $value = preg_replace("/\b(select|insert|update|delete)\b/i", '', $value);
- }
- return $value;
- }
-
- /**
- * 对字段值两边加引号,以保证数据库安全
- * @param $value 数组值
- * @param $key 数组key
- * @param $quotation
- */
- public function escape_string(&$value, $key='', $quotation = 1) {
- if ($quotation) {
- $q = '\'';
- } else {
- $q = '';
- }
- $value = $q.$value.$q;
- return $value;
- }
- }
- ?>
|