Ousland
侠客
侠客
  • UID67
  • 粉丝10
  • 关注0
  • 发帖数38
  • 社区居民
  • 阅读:7536
  • 回复:3

第四周作业 2014-8-13 崔景宇

楼主#
更多 发布于:2014-08-13 15:51
饮料已备好,周六中午给大家发福利
.

先上第二题,封装一个mysqli操作类;
<?php
   
/**
* mysqli 查询数据库;
* @Author Cui;
* @Data 2014/08/05
*/
class db_mysqli
{
    # mysqli 类;
    private $db;
       
    # 表;
    private $sqlTables;
       
    # where条件;
    private $sqlWhere;
       
    # 数据库字段;
    private $sqlFields;
       
    # 排序;
    private $sqlOrder;
       
    # 分页;
    private $sqlLimit;
       
    # prepare;
    private $sqlPrepare;
   
    # 数据;
    private $data;
   
    # 最后的sql语句;
    private $sql;
       
    # 预查询对象;
    private $stmt;    
   
    # 错误信息;
    private $error;
   
   
    # 构造方法;
    public function __construct( $connect ) {
   
        if ( !extension_loaded( 'mysqli' ) ) {
            exit( 'Mysqli Unload!' );
        }
   
        @$this->db = new mysqli( $connect['host'], $connect['user'], $connect['password'] );
   
        if ( mysqli_connect_errno() ) { 
            exit( mysqli_connect_error() );            
        }    
           
        $this->db->select_db( $connect['db'] );
        $this->db->set_charset( $connect['charset'] );
   
    }
   
    # 魔术方法;
    public function __invoke ( $tables = '' ) {
        $this->table( $tables );
        return $this;
    }
   
    public function __call( $method = "", $var = "" ) {
        exit( '你调用了一个未定义的方法'.$method.'!' );
    }
   
    # 设置表;
    public function table( $tables ) {
        if ( is_string( $tables ) ) {
            $tables = array( $tables );
        }
        $this->sqlTables = $tables;
        return $this;
    }
   
    # 设置字段信息;
    public function field( $fields = '' ) {
        if ( is_string( $fields ) ) {
            $fields = array( $fields );
        }
   
        if ( !is_array( reset( $fields ) ) ) {
            $fields = array( $fields );
        }
   
        $this->sqlFields = $fields;
        return $this;
    }
   
    # 设置where条件;
    public function where( $where = '' ) {
        if ( is_string( $where ) ) {
            $where = array( $where );
        }
   
        $this->sqlWhere = $where;
        return $this;
    }
   
    # 设置排序;
    public function order( $order = '' ) {
        if ( is_string( $order ) ) {
            $order = array( $order );
        }    
   
        $this->sqlOrder = $order;
        return $this;
    }
   
    # 设置排序;
    public function limit( $limit = '' ) {    
        if ( is_string( $limit ) || is_integer( $limit ) ) {
            $limit = array( $limit );
        }
   
        $this->sqlLimit = $limit;
        return $this;
    }
   
    # 连表方法;
    public function join( $on = '' ) {
        /*暂无*/
    }
   
    # 查询方法;
    public function select() {
        return $this->core( 'select' );
    }
   
    # insert方法;
    public function add( $data  = '' ) {
        $this->data = $data;
        return $this->core( 'add' );
    }
   
    # updata方法;
    public function save( $data = '' ) {
        $this->data = $data;
        return $this->core( 'save' );
    }
   
    # delete方法;
    public function delete() {
        return $this->core( 'delete' );
    }
   
    # 预处理方法:
    public function prepare() {
        $var = func_get_args();
        if ( count( $var ) < 1 )return $this;
   
        if ( count( $this->sqlTables ) <= 1 ) {
            if ( count($var) >= 1 && !is_array( reset($var) ) ) {
                $var = array( $var );
            }
        }
   
        if ( count( $this->sqlTables ) >1 && !is_array( reset($var) ) ) {
            exit ("预处理参数传入不正确!");
            return false;
        }
   
        # 取类型;
        foreach ( $var as $key => $value ) {
            $type = array_map( function( $v ){
                return substr( gettype( $v ),0,1);
            }, $value);
            array_unshift( $var[$key], implode( $type ) );
        }
   
        $this->sqlPrepare = $var;
        return $this;
    }
   
    # 开启事务;
    public function startTrans( $flag ) {
        if ( !is_bool( $flag ) ) {
            $this->error = '事务开启参数错误';
            return false;
        }
        return $this->db->autocommit( !$flag );
    } 
   
    # 提交事务;
    public function commit() {
        $res = $this->db->commit();
        $this->startTrans( false );
        return $res;
    }
   
    # 回滚事务;
    public function rollback() {
        $res = $this->db->rollback();
        $this->startTrans( false );
        return $res;
    }
   
    # 核心方法;
    private function core( $action ) {
   
        $tables = $this->sqlTables;
   
        if ( empty( $tables ) ) {
            $this->error = "未定义查询表;";
            return false;
        }
   
        switch ( $action ) {
            case 'select':
                   
                $sql = $this->build_select_sql();
                   
                break;
               
            case 'save':
   
                $data = $this->get_write_data();
                   
                if ( !$data ) {
                    return false;
                }
   
                if ( false === $this->check_where() ) {
                    return false;
                }
   
                $sql = $this->build_update_sql( $data );
                   
                break;
   
            case 'add':
                   
                $data = $this->get_write_data();
                   
                if ( !$data ) {
                    return false;
                }
   
                $sql = $this->build_insert_sql( $data );
                   
                break;
               
            case 'delete':
                   
                if ( false === $this->check_where() ) {
                    return false;
                }
   
                $sql = $this->build_delete_sql();
   
                break;
        }
   
        if ( count( $sql ) <= 1 ) {
   
            $sql  = reset( $sql );
               
            if ( is_array( $this->sqlPrepare ) && !empty( $this->sqlPrepare  ) ) {
                $result = $this->execute( $sql );
            } else {
                $result = $this->query( $sql );
            }
               
        } else {
               
            if ( is_array( $this->sqlPrepare ) && !empty( $this->sqlPrepare  ) ) {
                exit('暂不支持多语句预处理;');
            } else {
                $result = $this->multi_query( $sql );
            }
        }
   
        if ( false === $result ) {
            $this->error = $this->db->error ?: $this->stmt->error;
            return false;
        }
   
        return $this->get_result( $result, $action );
   
    }
   
    # 构建sql语句;
    private function build_select_sql( ) {
           
        $tables = $this->sqlTables;
        $fields = $this->sqlFields;
        $where = $this->sqlWhere;
        $order = $this->sqlOrder;
        $limit = $this->sqlLimit;
   
        $sql = array();
        foreach ( $tables as $key => $table ) {
            $sql_tmp = '';
            $sql_tmp .= 'SELECT ';
            if ( !isset( $fields[$key] ) ) {
                 $fields[$key] = '*';
            }
            if ( is_array( $fields[$key] ) ) {
                array_walk( $fields[$key], function( &$v ) {
                    $v = '`'.$v.'`';
                });
                $fields[$key] = implode( ' , ', $fields[$key] );
            }
            $sql_tmp .= $fields[$key];
            $sql_tmp .= ' FROM '.'`'.$table.'`';
   
            !empty( $where[$key] ) && $sql_tmp .= ' WHERE '.$where[$key];
            !empty( $order[$key] ) && $sql_tmp .= ' ORDER BY '.$order[$key];
            !empty( $limit[$key] ) && $sql_tmp .= ' LIMIT '.$limit[$key];
               
            $sql[$key] = $sql_tmp;
        }
           
        return $sql;
       
    }
   
    private function build_insert_sql( $data ) {
        $tables = $this->sqlTables;
        $sql = array();
        foreach ( $tables as $key => $table ) {
               
            $sql_tmp = '';            
            $sql_tmp .= 'INSERT INTO '.'`'.$table.'`';
               
            $col = array_keys( $data[$key] );
            $callFunc = 
            array_walk( $col, function ( &$v ) {
                $v = '`'.$v.'`';
            } );            
            $col = ' ( '.implode( ' , ', $col ).' ) ';
               
            $val= array_values( $data[$key] );            
            array_walk( $val, function ( &$v ) {
                $v = $v == '?' ? $v : '\''.$v.'\'' ;
            } );            
            $val = ' ( '.implode( ' , ', $val ).' ) ';
               
            $sql_tmp .= $col;
            $sql_tmp .= ' VALUES '.$val;
            $sql[$key] = $sql_tmp;
        }
        return $sql;
    }
   
    private function build_update_sql( $data ) {
        $tables = $this->sqlTables;
        $where = $this->sqlWhere;
        $sql = array();
        foreach ( $tables as $key => $table ) {
            $sql_tmp = '';
            $sql_tmp .= 'UPDATE '.'`'.$table.'`';
               
            $set = array();
   
            foreach ( $data[$key] as $col => $val ) {
                $val = $val == '?' ? $val : '\''.$val.'\'' ;
                $set[] = '`'.$col.'` = '.$val;
            }
            $set = implode( ' , ', $set );
               
            $sql_tmp .= ' SET '.$set;
            $sql_tmp .= ' WHERE '.$where[$key];
            $sql[$key] = $sql_tmp;
        }
        return $sql;
    }
   
    private function build_delete_sql() {
        $tables = $this->sqlTables;
        $where = $this->sqlWhere;
        $sql = array();
        foreach ( $tables as $key => $table ) {
            $sql_tmp = '';
            $sql_tmp .= 'DELETE FROM '.'`'.$table.'`';
            $sql_tmp .= ' WHERE '.$where[$key];
            $sql[$key] = $sql_tmp;
        }
        return $sql;
    }
   
    # 单语句查询;
    public function query( $sql ) {
        $this->sql = $sql;
        $this->clean_attribute();
        return $this->db->query( $sql );
    }
   
    # 单语句预查询;
    public function execute( $sql, $flag = false ) {
   
        $param = array_shift( $this->sqlPrepare );
   
        $result = $this->db->prepare( $sql );
   
        /*5.3是引用传递*/
        if ( strnatcmp( phpversion(), '5.3' ) >= 0 ) {
            for ( $i = 0; $i < count( $param ); $i++ ) {
                $param[$i] = &$param[$i]; 
            }
        }
   
        @call_user_func_array( array( $result, "bind_param" ), $param );
        if ( !$flag ) {
            $this->sql = $sql;
            $this->clean_attribute();
        }
           
        !is_object( $this->stmt  ) && $this->stmt = $result;
           
        return $result->execute();
   
    }
   
    # 多语句查询;
    public function multi_query( $sqlArr ) {
        $sql = implode(';', $sqlArr );
        $this->sql = $sql;
        $this->clean_attribute();
        return $this->db->multi_query( $sql );
    }
       
    # 获取结果集内容;
    public function get_result( $result, $action ) {
        switch ( $action ) {
            case 'select':
                $result =  $this->get_fetch_assoc( $result );
                break;
            case 'add':
                $result =  $this->get_insert_id();
                break;
            case 'save':
                $result =  $this->get_affected_rows();
                break;
            case 'delete':
                $result =  $this->get_affected_rows();
                break;
        }
   
        return $result;
   
    }
   
    # 将结果集转化为数组
    public function get_fetch_assoc( $result = '' ) {
           
        $res = array();
        $key = 1;
        do {
               
            if ( is_object( $this->stmt ) ) {
                $result = $this->stmt->get_result();
                $this->stmt = '';
            } else {
                $result = is_object( $result ) && $key <= 1 ? $result : $this->db->store_result();
            }
   
            if ( $result ) {
                while ( $row = $result->fetch_assoc() ) {
                   $res[$key][] = $row;
                }
                $result->free();
            }    
               
            $key++;
   
        } while ( $this->db->more_results() && $this->db->next_result() );
   
        if ( count( $res ) == 1 ) {
            $res = reset( $res );
        }
   
        return $res;
    }
   
    # 获取数据插入后的id
    public function get_insert_id() {
        $insertId = array();
           
        do {
               
            $insertId[] = $this->db->insert_id;
           
        } while ( $this->db->more_results() && $this->db->next_result() );
           
        if ( count( $insertId ) == 1 ) {
            $insertId = reset( $insertId );
        }
           
        return $insertId;
    }
   
    # 获取数据更新/删除的影响的行数;
    public function get_affected_rows() {
        $affectedRows = array();
           
        do {
               
            $affectedRows[] = $this->db->affected_rows;
           
        } while ( $this->db->more_results() && $this->db->next_result() );
   
        if ( count( $affectedRows ) == 1 ) {
            $affectedRows = reset( $affectedRows );
        }
        return $affectedRows;
    }
   
    # 获取写入数据;
    private function get_write_data() {
        $data = $this->data;
   
        if ( !$data || !is_array( $data ) ) {
            $this->error = '数据非法!';
            return false;
        }
           
        if ( count( $this->sqlTables ) > 1 ) {
            for( $i = 0; $i< count( $this->sqlTables ); $i++ ) {
                if ( !is_array( current( $data ) ) ) {
                    $this->error = '需要写入的数据与数据表 数量不一致!';
                    return false;
                }
            }
            return $data;
        }
   
        if ( count( $this->sqlTables ) == 1 && is_array( reset( $data ) ) ) {
            return $data;
        }
   
        return array( $data );
    }
   
    # 增删改时 检查where 
    private function check_where() {
        if ( !$this->sqlWhere ) {
            $this->error = '没有条件,危险操作!';
            return false;
        }
   
        if ( count( $this->sqlWhere ) < count( $this->sqlTables ) ) {
            $this->error = '条件与数据表 数量不一致! 危险!';
            return false;
        }
   
        return true;
    }
   
    # 语句执行后清空部分属性;
    private function clean_attribute( $noRemove = array( 'db', 'sqlTables', 'error', 'sql' ) ) {
        $attributes = get_class_vars( get_class( $this ) );
        foreach ( $attributes as $key => $value ) {
            if ( !in_array( $key, $noRemove ) ) {
                $this->$key = '';
            }
        }
    }
   
    # 获取最后执行的sql语句;
    public function getLastSql() {
        return $this->sql;
    } 
   
    # 获取错误信息;
    public function getError() {
        return $this->error;
    }
   
    public function __destruct() {
        $this->db->close();
        $this->clean_attribute( array() );
    }
   
}
   
   
// 测试
$config = array(
    'host' => 'localhost',
    'user' => 'root',
    'password' => 'admin',
    'db' => 'test',
    'charset' => 'utf8'
);
$M = new db_mysqli( $config );
   
#单语句增删改查;
$data = array('title' => time());
$res = $M('title')->add( $data ); //返回ID号;
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
//INSERT INTO `title` ( `title` )  VALUES  ( '1407911896' );
   
$res = $M('title')->field( 'title' )->where('id > 2')->limit(10)->order('id desc')->select();
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
//SELECT `title` FROM `title` WHERE id > 2 ORDER BY id desc LIMIT 10;
   
   
   
$res = $M('title')->where('id > 10')->delete(); //返回影响行数;
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
//DELETE FROM `title` WHERE id > 10;
   
#事务
$M->startTrans( true );
   
$data = array('title'=>'updat4e!');
$res = $M('title')->where('id = 1')->save( $data );//返回影响行数;
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
$M->rollback();
   
   
#单语句预处理增删改查;
$data = array( 'id' => '?', 'title' => '?' );
$res = $M('title')->prepare( 12,'prepare' )->add( $data );
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
   
$res = $M('title')->where('id > ?')->prepare(5)->order('id desc')->select();
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
   
$res = $M('title')->where('id > ? and title = ?')->prepare(array(9,'update!'))->delete();
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
   
$data = array('title'=>'?');
$res = $M('title')->where('id > ?')->prepare( 'update!' , 6 )->save( $data );
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
   
#多语句查询 原有的参数变为数组;
$data = array();
$data[0] = array('title' => '1'.time());
$data[1] = array('title' => '2'.time());
$tables = array( 'title','title' );
$res = $M( $tables )->add( $data ); //返回ID号;
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
/*INSERT INTO `title` ( `title` )  VALUES  ( '11407913979' ) ;
INSERT INTO `title` ( `title` )  VALUES  ( '21407913979' )*/
   
$field = array();
$field[0] = array('title');
$field[1] = array('id');
$res = $M($tables)->field( $field )->where(array('id > 5', 'id <= 5'))->limit(10)->order('id desc')->select();
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
/*
SELECT `title` FROM `title` WHERE id > 5 ORDER BY id desc LIMIT 10;
SELECT * FROM `title` WHERE id <= 5
*/
   
$res = $M($tables)->where(array('id = 5', 'id = 6'))->delete(); //返回影响行数;
var_dump( $res );
var_dump( $M->getLastSql() );
var_dump( $M->getError() );
/*
DELETE FROM `title` WHERE id = 5;
DELETE FROM `title` WHERE id = 6
*/
喜欢3

最新喜欢:

BlueRavenBlueRa... cj_vviippcj_vvi... morganamorgan...
BlackTree
管理员
管理员
  • UID1
  • 粉丝116
  • 关注6
  • 发帖数715
  • 社区居民
  • 最爱沙发
  • 喜欢达人
  • 原创写手
沙发#
发布于:2014-08-15 10:19
景宇 的这mysli的类封装的很强大,不错
cj_vviipp
骑士
骑士
  • UID112
  • 粉丝4
  • 关注4
  • 发帖数39
  • 社区居民
板凳#
发布于:2014-11-12 22:05
很强大
BlueRaven
侠客
侠客
  • UID98
  • 粉丝4
  • 关注4
  • 发帖数26
地板#
发布于:2014-11-13 21:34
预处理方法中的获取字段类型一直没有一个好的解决方案,终于然我找到了!大牛交个朋友吧

返回顶部