美文网首页
php 封装PDO单例 2022-11-27

php 封装PDO单例 2022-11-27

作者: 阿然学编程 | 来源:发表于2022-11-26 13:30 被阅读0次
    <?php
    
    class Db
    {
        // 默认数据库配置(常量数据库配置)
        const DSN = 'mysql:host=127.0.0.1;dbname=www_test_cn;charset=utf8';
        const USER = 'www_test_cn'; //账号
        const PASS = 'test';  //密码
    
        // 保存DB对象的静态属性值
        private static $obj = null;
        // 保存PDO数据库操作对象
        private $link = null;
        // 保存操作的数据表
        private $table = null;
        // 保存所有表内的字段
        private $fields;
        // 保存主键名称
        private $pk;
        // 保存要查询的字段
        private $keys;
        // 保存查询条件
        private $where;
        // 保存排序条件
        private $order;
        // 保存分页条件
        private $limit;
        // 保存分组条件
        private $group;
        // 保存分组再筛选条件
        private $having;
    
        /**
         * 数据库 初始化操作
         */
        private function __construct($table, $config)
        {
            // 连接数据库相关设置
            $this->connect($config);
            // 设置操作的数据表
            $this->setTable($table);
            // 得到表内所有的字段
            $this->getField();
        }
    
        /**
         * 设置操作的表名(静态方法)
         * @param string $table 操作的表名
         * @param array $config 数据库配置选项
         * @return object 返回连接好的PDO对象
         */
        public static function table($table, $config = [])
        {
            if (self::$obj === null) {
                // 实例化PDO对象
                self::$obj = new self($table, $config);
            }
            //返回PDO对象
            return self::$obj;
        }
    
        /**
         * 连接数据库相关设置
         * @param array $config 数据库配置选项
         */
        protected function connect($config = [])
        {
            // 如果配置项为空,则使用默认的常量配置
            if (empty($config)) {
                $config = [
                    'dsn' => self::DSN,
                    'user' => self::USER,
                    'pass' => self::PASS
                ];
            }
            // 实例化PDO的对象
            try {
                $options = [
                    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                    \PDO::ATTR_EMULATE_PREPARES => false,
                    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC
                ];
    
                $this->link = new \PDO($config['dsn'], $config['user'], $config['pass'], $options);
            } catch (\PDOException $e) {
                throw new \Exception("数据库连接失败: " . $e->getMessage());
            }
        }
    
        /**
         * 设置操作的数据表
         * @param string $table 要操作的数据表
         */
        protected function setTable($table)
        {
            $this->table = $table;
        }
    
    
        /**
         * 查询多条数据
         * @return 二维数组/空数组
         */
        public function select()
        {
            $keys = '*'; // 默认查全部
            // 判断有无字段条件
            if (!empty($this->keys)) {
                $keys = $this->keys;
                $this->keys = null; // 每次清除查询条件
            }
    
            $where = ''; // 默认无where条件
            // 判断有无 where条件
            if (!empty($this->where)) {
                // 注意WHERE后面有空格,再拼接where条件
                $where = 'WHERE ' . $this->where;
                $this->where = null;// 每次用完清除条件
            }
    
            $order = '';
            // 判断有无order条件
            if (!empty($this->order)) {
                $order = 'ORDER BY ' . $this->order;
                $this->order = null;// 每次用完清除条件
            }
    
            $limit = '';
            // 判断有无limit条件
            if (!empty($this->limit)) {
                $limit = 'LIMIT ' . $this->limit;
                $this->limit = null;// 每次用完清除条件
            }
    
            $group = '';
            // 判断有无group条件
            if (!empty($this->group)) {
                $group = 'GROUP BY ' . $this->group;
                $this->group = null;// 每次用完清除条件
            }
    
            $having = '';
            // 判断有无having条件
            if (!empty($this->having)) {
                $having = 'HAVING ' . $this->having;
                $this->having = null;// 每次用完清除条件
            }
    
            // 查询的sql语句
            $sql = "SELECT {$keys} FROM {$this->table} {$where} {$group} {$having} {$order} {$limit}";
    
            try {
                // 执行查询
                $stmt = $this->link->query($sql);
                // 处理结果集
                $result = $stmt->fetchAll();
            } catch (\PDOException $e) {
                throw new \Exception("Query failed: " . $e->getMessage());
            }
    
            // 返回结果
            return $result;
        }
    
    
        /**
         * 查单条数据
         * @param str $findValue 指定查询的字段值
         * @param str $findKey 指定查询的字段条件
         * @return bool/array 返回一维数组或false
         */
        public function find($findKey = null, $findValue)
        {
            $keys = '*'; //默认查全部
            //判断有无字段条件
            if (!empty($this->keys)) {
                $keys = $this->keys;
                $this->keys = null; // 每次用完清除查询条件
            }
    
            // 无参2,则指定为主键
            if ($findKey === null) {
                $findKey = $this->pk; // 若无参数 `$findKey`,则默认使用主键作为查找条件
            }
    
            // SQL语句
            $sql = "SELECT {$keys} FROM {$this->table} WHERE {$findKey} = :findValue LIMIT 1";
    
            try {
                $stmt = $this->link->prepare($sql);
                $stmt->bindValue(':findValue', $findValue);
                $stmt->execute();
    
                $data = $stmt->fetch();
            } catch (PDOException $e) {
                throw new \Exception("Query failed: " . $e->getMessage());
            }
    
            return !empty($data) ? $data : false;
        }
    
    
        /**
         * 获取要查询的字段,对象链操作
         * @param arr $arr 以数组形式,指定要查询的字段
         * @param arr $func 以数组形式,指定SQL中统计函数
         * @return $this
         */
        public function field($arr, $func = [])
        {
            // 判断参数 是否是数组.如不是,直接返回自己
            if (!is_array($arr)) return $this;
    
            // 遍历$arr 删除非法字段(数据表里没有的字段)
            foreach ($arr as $key => $val) {
                if (!in_array($val, $this->fields)) {
                    unset($arr[$key]);
                }
            }
    
            // 如果处理好的参数为空,则直接返回自己
            if (empty($arr)) return $this;
    
            // 生成字段条件,存为属性,方便其它方法使用
            $this->keys = implode(',', $arr);
    
            // 判断有无传递参2
            if (!empty($func) && is_array($func)) {
                $this->keys = $this->keys . ',' . implode(',', $func);
            }
    
            // 返回自己,用于对象链操作
            return $this;
        }
    
    
        /**
         * 获取要查询的条件,对象链操作
         * @param str $where 指定要查询的条件
         * @return $this
         */
        public function where($where)
        {
            // 设置要查询的条件
            $this->where = $where;
            // 返回自己,用于对象链操作
            return $this;
        }
    
    
        /**
         * 获取排序的条件,对象链操作
         * @param str $order 指定排序条件
         * @return $this
         */
        public function order($order)
        {
            // 设置排序条件
            $this->order = $order;
            // 返回自己,用于对象链操作
            return $this;
        }
    
        /**
         * 获取分页条件,对象链操作
         * @param str $order 指定分页条件
         * @return $this
         */
        public function limit($limit)
        {
            // 设置分页条件
            $this->limit = $limit;
            // 返回自己,用于对象链操作
            return $this;
        }
    
        /**
         * 获取分组条件,对象链操作
         * @param str $group 指定分组条件
         * @return $this
         */
        public function group($group)
        {
            // 设置分组条件
            $this->group = $group;
            // 返回自己,用于对象链操作
            return $this;
        }
    
    
        /**
         * 获取分组再筛选条件,对象链操作
         * @param str $having 指定分组筛选条件
         * @return $this
         */
        public function having($having)
        {
            // 判断有无分组条件,无则直接返回$this,不进行操作
            if (!isset($this->group)) return $this;
            // 设置分组条件
            $this->having = $having;
            // 返回自己,用于对象链操作
            return $this;
        }
    
    
        /**
         * 新增数据
         * @param array $data 要添加的数据
         * @return 新增成功返回ID/失败返回false
         */
        public function insert($data = [])
        {
            if (empty($data)) {
                $data = $_POST; // 默认使用 $_POST 数据
            }
    
            $list = [];
            foreach ($data as $k => $v) {
                if (in_array($k, $this->fields)) {
                    $list[$k] = $v;
                }
            }
    
            $keys = implode(',', array_keys($list));
            $values = implode("','", array_values($list));
    
            $sql = "INSERT INTO {$this->table} ({$keys}) VALUES ('{$values}')";
    
            return $this->execute($sql);
        }
    
        /**
         * 删除数据
         * @param str $delValue 指定删除的字段值
         * @param str $delKey 指定删除的字段条件
         * @return bool 成功返回true/失败返回false
         */
        public function delete($delKey = null, $delValue)
        {
            if ($delKey === null) {
                $delKey = $this->pk; // 若无参数 `$delKey`,则默认使用主键进行删除操作
            }
    
            $sql = "DELETE FROM {$this->table} WHERE {$delKey} = :delValue";
            $stmt = $this->link->prepare($sql);
            $stmt->bindValue(':delValue', $delValue);
    
            return $stmt->execute();
        }
    
        /**
         * 更新数据
         * @param array $data 要更新的数据
         * @return bool 成功返回true/失败返回false
         */
    
        public function update($conditions = [], $data = [])
        {
            // 如果数据为空,则将POST数据赋值给$data变量
            if (empty($data)) {
                $data = $_POST;
            }
    
            // 筛选出有效字段的数据
            $list = [];
            foreach ($data as $k => $v) {
                if (in_array($k, $this->fields) && $k != $this->pk) {
                    $list[] = "`{$k}`='{$v}'";
                }
            }
    
            // 生成SET条件
            $set = implode(',', $list);
    
            // 根据给定的条件生成WHERE条件
            $where = '';
            foreach ($conditions as $key => $value) {
                $where .= "`{$key}` = '{$value}' AND ";
            }
            $where = rtrim($where, ' AND ');
    
            // SQL查询语句
            $sql = "UPDATE {$this->table} SET {$set} WHERE {$where}";
    
            // 执行查询并返回true或false
            return $this->execute($sql);
        }
    
    
        /**
         * 执行 查询的 SQL语句的操作
         * @param string $sql 指定执行的SQL语句
         * @return array  返回数组(二维数组/空数组)
         */
        public function query($sql)
        {
            $stmt = $this->link->query($sql);
            return $stmt->fetchAll();
        }
    
    
        /**
         * 执行 增删改 SQL语句的操作
         * @param string $sql 指定执行的SQL语句
         * @return bool/int  操作失败返回false/删改成功返回true/新增成功返回ID
         */
        public function execute($sql)
        {
            $result = $this->link->exec($sql);
            if ($result === 0) {
                // 增删改失败
                return false;
            } else {
                if ($this->link->lastInsertId() > 0) {
                    //新增成功 返回自增ID
                    return $this->link->lastInsertId();
                } else {
                    // 删改成功返回true
                    return true;
                }
            }
        }
    
    
        /**
         * 获取数据表内所有的字段
         * @return null 无返回值,执行结果会存储到fields属性值中
         */
        private function getField()
        {
            //查询表结构
            $sql = "DESC {$this->table}";
            $list = $this->query($sql);
            // 遍历得到全部字段名字
            $fields = [];
            foreach ($list as $val) {
                $fields[] = $val['Field'];
                // 获取主键
                if ($val['Key'] == 'PRI') {
                    $this->pk = $val['Field'];
                }
            }
            //给属性赋值
            $this->fields = $fields;
        }
    
    
        /**
         * 私有化克隆方法
         * @return 无
         */
        private function __clone()
        {
            // 该对象无法被克隆
        }
    
    }
    
    • 使用示例
    <?php
    
    
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    
    require dirname(__FILE__) . '/Db.class.php';
    
    
    function test()
    {
        //数据库配置
        $db_config = [
            'dsn' => 'mysql:host=127.0.0.1;dbname=tp51;charset=utf8',
            'user' => 'root',
            'pass' => 'rootv8',
        ];
    
        $data = [
            'code' => 112001,
            'name' => 222222
        ];
    
        //设置数据表和相关配置(配置不写则使用默认配置)
        $db = Db::table('region_1_provinces', $db_config);
    
        // select查询
        $res = $db->where('id>12')->select();
    
        // find单条查询
        $res = $db->find('id', 1);
    
        //update更新
        $res = $db->update(array('id' => 40), $data);
    
        //insert插入
        $res = $db->insert($data);
    
        //delete删除
        $res = $db->delete('code', 111);
    
        dump($res);
    }
    
    //调用
    test();
    ?>
    
    

    相关文章

      网友评论

          本文标题:php 封装PDO单例 2022-11-27

          本文链接:https://www.haomeiwen.com/subject/vflcfdtx.html