静态PDO基础操作封装

环境要求:PHP7.1 PDO Extension

先贴代码

<?php
/**
 * PDO FOR MySQL Extension
 * Author 空城 <694623056@qq.com>
 * Copyright 2017 空城
 * CreateDate 2017-12-14
 */

class mysql_pdo
{
    // Host address
    public static $host     = '127.0.0.1';
    // Host port
    public static $port     = 3306;
    // Username
    public static $user     = 'root';
    // Password
    public static $pwd      = 'root';
    // Database
    public static $db       = '';
    // Character set
    public static $charset  = 'utf8mb4';
    // Persistent connection
    public static $pconnect = true;
    // Connection object
    public static $conn     = null;
    // Table name
    public static $table    = '';

    // Core container
    public static $data     = '';
    public static $field    = '*';
    public static $where    = '';
    public static $order    = '';
    public static $group    = '';
    public static $limit    = '';
    public static $join     = '';
    public static $bind     = [];
    public static $sql      = '';

    // Initialization
    public static function init(array $conf = array(), bool $reconnect = false):void
    {
        class_exists('PDO') or exit("PDO: class not exists.");
        empty($conf['host'])  or self::$host  = $conf['host'];
        empty($conf['port'])  or self::$port  = $conf['port'];
        empty($conf['user'])  or self::$user  = $conf['user'];
        empty($conf['pwd'])   or self::$pwd   = $conf['pwd'];
        empty($conf['db'])    or self::$db    = $conf['db'];
        empty($conf['table']) or self::$table = $conf['table'];
        if (is_null(self::$conn) || $reconnect) self::$conn = self::_connect();
    }

    // Query or Exec
    public static  function do(string $sql = '', bool $flag = false)
    {
        empty($sql) or self::$sql = $sql;
        $preg = 'INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|SELECT .* INTO|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK'; 
        if (preg_match('/^\s*"?(' . $preg . ')\s+/i', self::$sql)) return self::exec('', $flag);
        else return self::query('', self::$sql);
    }

    // Query
    public static function query(string $sql = '', bool $flag = false):array
    {
        $statm = self::_start($sql);
        $result = $statm->fetchAll(\PDO::FETCH_ASSOC);
        return $flag ? $result[0] : $result;
    }

    // Exec
    public static function exec(string $sql = '', bool $flag = false):int
    {
        $statm = self::_start($sql);
        $row = $statm->rowCount();
        return $flag ? self::$conn->lastInsertId() : $row;
    }

    // Insert 
    public static function insert(string $table = '', array $data = [], bool $flag = false):int
    {

        $table = !empty($data) ? $table : self::$table;
        $data = !empty($data) ? $data : self::$data;
        $insertData = [];
        if ( count($data) == count($data, 1) ) $insertData[0] = $data;
        else $insertData = $data;
        $lastId = 0;
        $row = 0;
        foreach ($insertData as $key => $data) {
            $data = self::_format($table, $data);
            $vals = [];
            foreach ($data as $key => $value) {
                $vals[] = self::_setBind(str_replace('`', '', $key), $value);
            }
            $keys = array_keys($data);
            
            self::$sql = 'INSERT INTO `' . trim($table) . '` (' . implode(',', $keys) . ') VALUES(' . implode(',', $vals) . ')';
            self::exec() && $flag && $row += 1;
        }
        
        $lastId = self::$conn->lastInsertId();
        unset($insertData,$data);
        return $flag ? $row : $lastId;
    }

    // Delete
    public static function del(string $table = '', array $where = []):int
    {
        $table = !empty($data) ? $table : self::$table;
        $where = !empty($where) ? self::_where($where) : self::_where(self::$where);
        if ('' === $where) return 0;
        self::$sql = 'DELETE FROM `'.trim($table).'` '.$where;
        unset($table, $where);
        return self::exec();
    }

    // Update
    public static function save(string $table = '', array $data = [], $where = []):int
    {
        $table = !empty($table) ? $table : self::$table;
        $data = !empty($data) ? $data : self::$data;
        $where = !empty($where) ? $where : self::$where;
        if (false == $where) {
            $key = self::_tbKey($table);
            $where = [];
            foreach ($key as $k => $v) {
                empty($data[$k]) or $where[$k] = $data[$k];
            }
            $where = self::_where($where);
        } else $where = self::_where($where);
        $data = self::_format($table, $data);
        $kv = [];
        foreach ($data as $key => $value) {
            $k = str_replace('`', '', $key);
            $k = self::_setBind($k, $value);
            $kv[] = $key.'='.$k;
        }
        $kv_str = implode(',', $kv);
        self::$sql = 'UPDATE `'.trim($table).'` SET '.trim($kv_str).' '.trim($where);
        unset($kv_str, $data, $kv, $table);
        if ('' === $where) return 0;
        return self::exec();
    }

    // Select
    public static function select(string $table = '', array $opt = []):array
    {
        $opt = self::_condition($table, $opt);
        $field = $opt['field'] = !empty($opt['field']) ? $opt['field'] : self::$field;
        if (is_array($field)) {
            foreach ($field as $key => $value) $field[$key] = self::_avoidKey($value);
            $field = implode(',', $field);
        }
        elseif(is_string($field) && $field != '');
        else $field = '*';
        self::$sql = 'SELECT '.$field.' FROM `'.$opt['table'].'` '.$opt['join'].$opt['where'].$opt['group'].$opt['order'].$opt['limit'];
        unset($opt);
        return self::query();
    }

    // Get a line
    public static function first(string $table = '', array $opt = []):array
    {
        self::$limit = '1';
        $result = self::select($table, $opt);
        return $result[0];
    }

    // Count
    public static function count(string $table = '', array $opt = []):array
    {
        $option = self::_condition($table,$opt);
        return self::_common($option, 'count');
    }

    // Avg
    public static function avg(string $table = '', array $opt = []):array
    {
        $option = self::_condition($table,$opt);
        return self::_common($option, 'avg');
    }

    // Sum
    public static function sum(string $table = '', array $opt = []):array
    {
        $option = self::_condition($table,$opt);
        return self::_common($option, 'sum');
    }

    // Min
    public static function min(string $table = '', array $opt = []):array
    {
        $option = self::_condition($table,$opt);
        return self::_common($option, 'min');
    }

    // Max
    public static function max(string $table = '', array $opt = []):array
    {
        $option = self::_condition($table,$opt);
        return self::_common($option, 'max');
    }

    // Dec
    public static function dec(string $table = '', $data = [], $where = []):int
    {
        return self::_setCol($table, $data, $where,'-');
    }

    // Inc
    public static function inc(string $table = '', $data = [], $where = []):int
    {
        return self::_setCol($table, $data, $where,'+');
    }

    // Clear
    public static function clear():void
    {
        self::$data  = '';
        self::$field = '*';
        self::$where = '';
        self::$order = '';
        self::$group = '';
        self::$limit = '';
        self::$bind  = [];
    }

    // SetAttribute
    public static function setAttr($key, $val):bool
    {
        !empty(self::$conn) or self::_connect();
        return self::$conn->setAttribute($key, $val);
    }

    // BeginTransaction
    public static function begin():bool
    {
        !empty(self::$conn) or self::_connect();
        return self::$conn->beginTransaction();
    }

    // Commit
    public static function commit():bool
    {
        !empty(self::$conn) or self::_connect();
        return self::$conn->commit();
    }

    // RollBack
    public static function rollBack():bool
    {
        !empty(self::$conn) or self::_connect();
        return self::$conn->rollBack();
    }

    // Connect
    protected static function _connect():void
    {
        $dsn = 'mysql:host='.self::$host.';port='.self::$port.';dbname='.self::$db;
        $options = [
                \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . self::$charset,
                \PDO::ATTR_PERSISTENT         => (bool)self::$pconnect
            ];
        try { 
            $dbh = new \PDO($dsn, self::$user, self::$pwd, $options);
            $dbh->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
            $dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
            $dbh->exec('SET NAMES ' . self::$charset);
        } catch (PDOException $e) { 
            exit('Connection failed: ' . $e->getMessage());
        }
        self::$conn = $dbh;
        unset($dsn, $dbh, $options);
    }

    // Mosaic SQL
    protected static function _condition(string $table, array $opt):array
    {
        $option = [];
        $option['table'] = !empty($table) ? $table : self::$table;
        $option['field'] = !empty($opt['field']) ? $opt['field'] : self::$field;
        $option['join'] = !empty($opt['join']) ? self::_join($opt['join']) :self::_join(self::$join);
        $option['where'] = !empty($opt['where']) ? self::_where($opt['where']) : self::_where(self::$where);
        $option['order'] = !empty($opt['order']) ? self::_order($opt['order']) : self::_order(self::$order);
        $option['group'] = !empty($opt['group']) ? self::_group($opt['group']) : self::_group(self::$group);
        $option['limit'] = !empty($opt['limit']) ? self::_limit($opt['limit']) : self::_limit(self::$limit);
        return $option;
    }

    // Exec SQL common function
    protected static function _start(string $sql = '')
    {
        empty($sql) or self::$sql = $sql;
        !empty(self::$conn) or self::_connect();
        $statm = self::$conn->prepare(self::$sql);
        $statm->execute(self::$bind);
        self::clear();
        return $statm;
    }

    // Common
    protected static function _common(array $opt, string $func):array
    {
        if (is_string($opt['field']) && $opt['field'] != "") {
            $strField = $opt['field'];
            $fieldArr = explode(",", $strField);
            $strField = '_'.implode("_,_", $fieldArr).'_';
        } elseif (is_array($opt['field'])) {
            $fieldArr = $opt['field'];
            $strField = '_'.implode("_,_", $opt['field']).'_';
        } else return false;

        foreach ($fieldArr as $v) {
            $val = self::_avoidKey($v);
            $alias = str_replace('.', '_', $val);
            $alias = ' AS '.(false === strpos($val, '*') ? $alias : '`'. $alias .'`');
            $strField = str_replace('_'.$v.'_', $func . '(' . $val . ') '.$alias, $strField);
        }
        self::$sql = 'SELECT '.$strField.' FROM `'.$opt['table'].'` '.$opt['join'].$opt['where'].$opt['group'].$opt['order'].$opt['limit'];
        unset($opt, $func, $fieldArr, $strField, $alias);
        $result = self::query();
        return count($result) == 1 && !empty($result[0]) ? $result[0] : $result;
    }

    // Set field
    protected static function _setCol(string $table = '', $data = '', $where = [], string $type):int
    {
        $table = !empty($table) ? $table : self::$table;
        $data  = !empty($data) ? $data : self::$data;
        $where = !empty($where) ? self::_where($where) : self::_where(self::$where);

        if (is_array($data)) {
            $new_data = [];
            foreach ($data as $key => $value) {
                if (is_string($key)) $new_data[$key] = $key.$type.abs($value);
                else $new_data[$value] = $value.$type.'1';
            }
        } elseif (is_string($data)) $new_data[$data] = $data.$type.'1';
        $kv = [];
        foreach ($new_data as $key => $value) {
            $kv[] = self::_avoidKey($key).'='.$value;
        }
        $kv_str = implode(',', $kv);
        self::$sql = 'UPDATE `'.trim($table).'` SET '.trim($kv_str).' '.trim($where);
        unset($data);
        if ('' === $where) return 0;
        return self::exec();
    }

    // Preprocessing
    protected static function _setBind(string $key, $value):string
    {
        if (empty(self::$bind[':'.$key])) {
            $k = ':'.$key;
            self::$bind[$k] = $value;
        } else {
            $k = ':'.$key.'_'.mt_rand(1,9999);
            while (!empty(self::$bind[':'.$k])) {
                $k = ':'.$key.'_'.mt_rand(1,9999);
            }  
            self::$bind[$k] = $value;
        }
        unset($key, $value);
        return $k;
    }

    // Join
    protected static function _join($opt):string
    {
        $join = '';
        if (is_string($opt) && '' !== trim($opt)) return $opt;
        elseif (is_array($opt)) {
            foreach($opt as $key => $value) {
                $mode = 'INNER';
                if (is_array($value)) {
                    if (!empty($value[2]) && 0 === strcasecmp($value[2], 'LEFT')) $mode = 'LEFT';
                    elseif (!empty($value[2]) && 0 === strcasecmp($value[2], 'RIGHT')) $mode = 'RIGHT';
                    $relative = !empty($value[3]) ? $value[3] : '=';
                    $condition = ' '.$mode.' JOIN '.$key.' ON '.self::_avoidKey($value[0]).$relative.self::_avoidKey($value[1]).' ';
                } else {
                    $condition = ' '.$mode.' JOIN '.$key.' ON '.$value.' ';
                }
                $join .= $condition;
            }
        }
        unset($opt);
        return $join;
    }

    // Where
    protected static function _where($opt):string
    {
        $where = '';
        if (is_string($opt) && '' !== trim($opt)) return ' WHERE '.$opt;
        elseif (is_array($opt)) {
            foreach($opt as $key => $value) {
                $k = self::_avoidKey($key);
                if (is_array($value)) {
                    $key = self::_setBind($key,$value[0]);
                    $relative = !empty($value[1]) ? $value[1] : '=';
                    $link    = !empty($value[2]) ? $value[2] : 'AND';
                    $condition = ' ('.$k.' '.$relative.' '.$key.') ';
                } else {
                    $key = self::_setBind($key,$value);
                    $link = 'AND';
                    $condition = ' ('.$k.'='.$key.') ';
                }
                $where .= $where !== '' ? $link.$condition : ' WHERE '.$condition;
            }
        }
        unset($opt);
        return $where;
    }

    // Order
    protected static function _order($opt):string
    {
        $order = '';
        if (is_string($opt) && '' !== trim($opt)) return ' ORDER BY '._avoidKey($opt);
        elseif (is_array($opt)) {
            foreach($opt as $key => $value) {
                $link = ',';
                if (is_string($key)) {
                    if (0 === strcasecmp($value, 'DESC')) $condition = ' '.self::_avoidKey($key).' DESC ';
                    else $condition = ' '.self::_avoidKey($key).' ASC ';
                }  else $condition = ' '.self::_avoidKey($value).' ASC ';
                $order .= $order !== '' ? $link.addslashes($condition) : ' ORDER BY '.addslashes($condition);
            }
        }
        unset($opt);
        return $order;
    }

    // Limit
    protected static function _limit($opt):string
    {
        $limit = '';
        if (is_string($opt) && '' !== trim($opt)) return ' LIMIT '.$opt;
        elseif (is_array($opt) && 2 == count($opt)) $limit = ' LIMIT '.(int)$opt[0].','.(int)$opt[1];
        elseif (is_array($opt) && 1 == count($opt)) $limit = ' LIMIT '.(int)$opt[0];
        unset($opt);
        return $limit;
    }

    // Group
    protected static function _group($opt):string
    {
        $group = '';
        if (is_string($opt) && '' !== trim($opt)) return ' GROUP BY '._avoidKey($opt);
        elseif (is_array($opt)) {
            foreach($opt as $key => $value) {
                $link = ',';
                $condition = ' '.self::_avoidKey($value).' ';
                $group .= $group !== '' ? $link.addslashes($condition) : ' GROUP BY '.addslashes($condition);
            }
        }
        unset($opt);
        return $group;
    }

    // Format data
    protected static function _format(string $table, $data):array
    {
        if (!is_array($data)) return array();

        $tbColumn = self::_tbInfo($table);
        $res = [];
        foreach ($data as $key => $val) {
            if (!is_scalar($val)) continue;
            if (!empty($tbColumn[$key])) {
                $key = self::_avoidKey($key);
                if (is_int($val)) $val = intval($val);
                elseif (is_float($val)) $val = floatval($val); 
                elseif (preg_match('/^\(\w*(\+|\-|\*|\/)?\w*\)$/i', $val)) $val = $val;
                elseif (is_string($val)) $val = addslashes($val);
                $res[$key] = $val;
            }
        }
        unset($data);
        return $res;
    }

    // Table info
    protected static function _tbInfo(string $table = ''):array
    {
        $table = !empty($table) ? $table : self::$table;
        $sql = 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="'.$table.'" AND TABLE_SCHEMA="'.self::$db.'"';
        !empty(self::$conn) or self::_connect();
        $statm = self::$conn->prepare($sql);
        $statm->execute();
        $result = $statm->fetchAll(\PDO::FETCH_ASSOC);
        $res = [];
        foreach ($result as $key=>$value) {
            $res[$value['COLUMN_NAME']] = 1;
        }
        // unset($result, $statm);
        return $res;
    }

    // Get primary key
    protected static function _tbKey(string $table):array
    {
        $sql = 'SELECT k.column_name FROM information_schema.table_constraints t JOIN information_schema.key_column_usage k USING (constraint_name,table_schema,table_name) WHERE t.constraint_type="PRIMARY KEY" AND t.table_schema="'.self::$db.'" AND t.table_name="'.$table.'"';
        !empty(self::$conn) or self::_connect();
        $statm = self::$conn->prepare($sql);
        $statm->execute();
        $result = $statm->fetchAll(\PDO::FETCH_ASSOC);
        $res = [];
        foreach ($result as $key=>$value) {
            $res[$value['column_name']] = 1;
        }
        unset($result, $statm);
        return $res;
    }

    // Avoid mistakes
    protected static function _avoidKey(string $value):string
    { 
        if ('*' == $value || false !== strpos($value,'(') || false !== strpos($value,'.'));
        elseif (false === strpos($value,'`')) $value = '`'.trim($value).'`';
        return $value; 
    }
}

基本使用

兼容两种写法,自动绑定与参数形式,参数形式写法优先于自动绑定

自动绑定写法:

Example-1:初始化

// step_1:引入文件
require_once 'mysql.php';
// 取别名(可省略)
use mysql_pdo as db;
// 连接信息(可省略,可在文件内写好配置)
db::$host = '127.0.0.1';
db::$user = 'root';
db::$pwd = 'root';
db::$db = 'test';
// step_2:绑定操作信息
db::$tbale = 'tablename';
// step_3:开始使用
db::select();  // 该操作最终执行的语句是:SELECT * FROM `tablename`

Example-2:Insert操作

// 绑定操作表
db::$table = 'tablename';
// 绑定数据,如需插入多行数据,构建的数据为二维数组即可
db::$data = [
    'col_1' => 'value_1',
    'col_2' => 'value_2',
    'col_3' => 'value_3',
    'col_4' => 'value_4'
];
// 执行
db::insert();  
// 返回值为最后插入的ID,如果要获取插入的行数请使用传参写法 db::insert('tablename',$data,true) 参数形式无须绑定参数

Example-3:Delete操作

// 操作表,如果每次都对同一张表进行操作,则不需要重新绑定
db::$table = 'tablename';
// 绑定where条件,防止删表操作,在没有where条件下不会执行delete操作
db::$where = ['id' => 1] // 数组形式一 最终解析:[AND] `id` = 1 默认对比关系为 =,逻辑 AND
db::$where = ['id' => ['1','>','AND']] // 数组形式二 最终解析:[AND] `id` > 1
db::$where = 'id = 1'  //字符串形式 最终解析为: WHERE id = 1
// 执行
db::del();

Example-4:Update操作

 // 在绑定表的基础上绑定数据即可
db::$data = [
    'col_1' => 'value_1',
    'col_2' => 'update_2',
    'col_3' => 'update_3',
    'col_4' => 'update_4'
];
// 当上述上中col_1为主键时,value_1,将自动当WHERE条件,解析为: WHERE `col_1` = value_1,至少要存在一个主键

// 更新
db::save();
// 如果绑定$where条件,则上述主键效果将消失
db::$where = [opt...];  // 值的写法同上

Example-5:Select操作

// join表,绑定操作表与where绑定不再演示
db::$join = ['table_b'=>['table_a.id','table_b.aid','INNER','=']];
// 一维数组中的键名为连接表的表名,二维数组中前两个值为连接条件-必填项,第三个默认为INNER,第四个默认为=

db::$join = ['table_b'=>'LEFT JOIN table_b ON table_a.id=table_b.aid'];
//当值为一个字符串时,将直接拼接

// 分组查询 
db::$group = ['sex','age'];  // 值为要分组的列名字即可
db::$group = 'sex'           // 值为字符串时直接拼接为 GROUP BY sex

// 排序
db::$order = ['id' => 'DESC'];  // 关联数组将解析成 ORDER BY `id` DESC
db::$order = ['id'];              // 索引数组将解析成 ORDER BY `id` ASC,默认为ASC排序
db::$order = 'id';              // 字符串将解析成 ORDER BY id 自动拼接

// 分页
db::$limit = [0,10]  // 存在两个值时将解析为 LIMIT 0,10;
db::$limit = [1]     // 存在一个值时将解析为 LIMIT 1;
db::$limit = '0,20'  // 字符串将解析为 LIMIT 0,20;

// 查询
db::select();  // 多条
db::first();   // 第一条

Example-6:聚合函数

db::count(); // count

db::sum();   // sum

db::avg();   // avg

db::min();   // min

db::max();   // max

Example-7:附加1

db::begin();              // 开启事务

db::commit();              // 提交事务

db::rollBack();          // 回滚事务

db::setAttr($key, $val); // 设置PDO属性

db::dec();                  // 字段自增,需绑定数据 db::$data = ['age'=>2]该自增步长为2,省略则默认为1

db::inc();                  // 字段自增,需绑定数据 db::$data = ['age'=>2]该自减步长为2,省略则默认为1

db::do($sql, [$flag]);      //执行一条SQL语句,不分查询还是执行,自动分配.第二个参数同下

db::query($sql,[$flag]); //执行一条有结果集的SQL语句, $flag 默认为false,为true是返回一条记录

db::exec($sql, [$flag]); //执行一条无结果集的SQL语句, $flag 默认为false,为true时返回insert语句的插入的ID,其他语句无效

// 执行拼接SQL可使用预处理绑定参数形式,然后绑定$bind即可
$sql = 'UPDATE `tablename` SET col_a=:col_a WHERE id=:id';
db::$bind = [':col_a' => 'update_a',':id'=>1];
db::do($sql); //或者 db::exec($sql);

db::clear() // 该方法将重置$data,$field,$where,$order,$group,$limit,$join,$bind数据,默认每执行一次语句将自动重置

db::init([conf...], $reconnect = false); // conf数组的值可为数据库基本配置(host,user,pwd等) $reconnext为true是将重新连接mysql

传参写法

Example-8:附加2

// insert
db::inster('tablename',[data...],$where);

// delete
db::del('tablename', $where);

// update
db::save('tablename', [data...], $where);

// select
db::select('tablename',[opt..]);  //opt参数可传入field,where,join,order,group,limit等信息

// first
db::first('tablename',[opt..]);   //opt参数同上

// avg
db::avg('tablename',[opt..]);        //opt参数同上

// count
db::count('tablename',[opt..]);   //opt参数同上

// sum
db::sum('tablename',[opt..]);     //opt参数同上

// min
db::min('tablename',[opt..]);     //opt参数同上

// max
db::max('tablename',[opt..]);     //opt参数同上

// dec
db::dec('tablename',[data..],$where);    //参数说明同绑定参数

// inc
db::inc('tablename',[data..],$where);    //参数说明同绑定参数

本文出自个人博客
最好的安排 转载请注明出处!

    原文作者:SQL
    原文地址: https://segmentfault.com/a/1190000012432571
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞