zoukankan      html  css  js  c++  java
  • 简易封装PDO的操作类

    <?php
    ini_set('display_errors', true);
    
    final class DB {
        private static $db;
        public static function getInstance(): PDO {
            if(!self::$db instanceof PDO) {
                new self();
            }
            return self::$db;
        }
        private function __clone() {}
        private function __construct() {
            $config = parse_ini_file('./db.ini');
            $dsn = sprintf('mysql:localhost=%s;dbname=%s;port=%d;charset=%s', $config['host'], $config['dbname'], $config['port'], $config['charset']);
            try{
                self::$db = new PDO($dsn, $config['user'], $config['password']);
            }catch(PDOException $e) {
                exit($e->getMessage());
            }
        }
    }
    
    class Statement {
        private static $statement;
        private $state;
        private function __construct(PDO $db, string $sql) {
            $this->state = $db->prepare($sql);
        }
        public static function getInstance(PDO $db, string $sql) {
            if(!self::$statement instanceof Statement) {
                self::$statement = new self($db, $sql);
            }
            return self::$statement;
        }
        public function bindValue($key, $val) {
            return $this->state->bindValue($key, $val);
        }
        public function bindParam($key, $val) {
            return $this->state->bindParam($key, $val);
        }
        public function execute() {
            return $this->state->execute();
        }
        public function fetchOne() {
            return $this->state->fetch(PDO::FETCH_ASSOC);
        }
        public function fetchAll() {
            return $this->state->fetchAll(PDO::FETCH_ASSOC);
        }
        public function fetchColumn(int $index = null) {
            return $this->state->fetchColumn($index);
        }
        public function resetQuery() {
            return $this->state->closeCursor();
        }
        public function effectRow() {
            return $this->state->rowCount();
        }
        public function errorReason() {
            return $this->state->errorInfo()[2];
        }
    }
    
    /**建立方法的抽象基类
     * Class Base
     */
    abstract class Base {
        protected $db;
        protected $statement;
        public function __construct(string $sql) {
            $this->db = DB::getInstance();
            $this->statement = Statement::getInstance($this->db, $sql);
        }
        protected function exec() {
            return $this->statement->execute() ? true: $this->statement->errorReason() ?? 'SQL语句有误';
        }
    
        public function bindValue($key = null, $val = null) {
            if(func_num_args() === 0 || (!is_array($key) && !$val)) {
                return $this;
            } else if(is_array($key)) {
                foreach($key as $k => $v) {
                    $this->statement->bindValue($k, $v);
                }
            } else {
                $this->statement->bindValue($key, $val);
            }
            return $this;
        }
        public function bindParam($key = null, $val = null) {
            if(func_num_args() === 0 || (!is_array($key) && !$val)) {
                return $this;
            } else if(is_array($key)) {
                foreach($key as $k => $v) {
                    $this->statement->bindParam($k, $v);
                }
            } else {
                $this->statement->bindParam($key, $val);
            }
            return $this;
        }
        public static function getDB(): PDO {
            return DB::getInstance();
        }
    }
    
    class Query extends Base{
        private function queryRes(bool $is_all = false) {
            $res = $this->exec();
            if($res === true) {
                $data = $is_all? $this->statement->fetchAll(): $this->statement->fetchOne();
                return $data === false? []: $data;
            }
            return $res;
        }
        public function one() {
            return $this->queryRes(false);
        }
        public function all() {
            return $this->queryRes(true);
        }
        public function fetchColumn($index = 0) {
            $res = $this->exec();
            if($res) {
                $data = $this->statement->fetchColumn($index);
                return $data === false? '': $data;
            }
            return $res;
        }
        public function __destruct() {
            $this->statement->resetQuery();
        }
    }
    
    class Operate extends Base{
        public function execute() {
            $res = $this->exec();
            if($res === true) {
                return $this->statement->effectRow();
            }
            throw new PDOException($res);
        }
    
        public static function beginTransaction($fn) {
            if(!$fn) {
                return false;
            }
            self::getDB()->beginTransaction();
            try{
                call_user_func($fn);
                return self::getDB()->commit()? true: false;
            }catch(PDOException $e) {
                self::getDB()->rollBack();
                throw $e;
            }
        }
        //注意:如果在事务中进行调用,那么就有可能获取不到
        public static function lastInsertId() {
            return self::getDB()->lastInsertId();
        }
    }
    
    //$res = (new Query('SELECT `u`.`user`, `temp`.`pwd` FROM `user` AS `u` LEFT JOIN (SELECT `id`, `pwd` FROM `user`) AS `temp` ON `temp`.`id` = `u`.`id` WHERE `u`.`id` > :id'))->bindValue(':id', 3)->all();
    //var_dump($res);
    //$res = (new Query('SELECT * FROM `user`'))->all();
    //var_dump($res);
    //$res = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
    //    ':user' => 'are you ok???',
    //    ':id' => 1
    //])->execute();
    //var_dump($res);
    
    //Operate::getDB()->beginTransaction();
    //try{
    //    $res1 = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
    //        ':user' => 'tt',
    //        ':id' => 1
    //    ])->execute();
    //    $res2 = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
    //        ':user' => 'tt',
    //        ':id' => 2
    //    ])->execute();
    //    if($res1 === true && $res2 === true) {
    //        Operate::getDB()->commit();
    //    }
    //}catch(PDOException $e) {
    //    Operate::getDB()->rollBack();
    //    throw $e;
    //}
    
    //$res1 = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
    //    ':user' => 'tt',
    //    ':id' => 1
    //])->execute();
    //$res2 = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
    //    ':user' => 'tt',
    //    ':id' => 2
    //])->execute();
    //var_dump($res1);
    //var_dump($res2);
    
    //$res = Operate::beginTransaction(function() {
    //    (new Operate('INSERT INTO `user` (`user`, `pwd`) VALUES (:user, :pwd)'))->bindValue([
    //        ':user' => 'wakaka',
    //        ':pwd' => 'nono'
    //    ])->execute();
    //});
    //var_dump($res);
    
    (new Operate('INSERT INTO `user` (`user`, `pwd`) VALUES (:user, :pwd)'))->bindValue([
        ':user' => 'wakaka',
        ':pwd' => 'nono'
    ])->execute();
    var_dump(Operate::lastInsertId());
    ?>
  • 相关阅读:
    c#中结构与类的区别(转载CSDN.NET)
    初识.net反射技术(转载cnblogs)
    C#利用反射动态调用类成员[转载]
    页面局部无刷新汇总(转载cnblogs)
    范型的用法大全
    Abstract Class 和 Interface用法
    命名的方法 匿名方法 对委托进行实例化
    ApplyStyle 方法
    类型反射的例子(转载)
    out 和 ref 传递数组参数方法
  • 原文地址:https://www.cnblogs.com/rickyctbu/p/11074821.html
Copyright © 2011-2022 走看看