DbPool.php 7.5 KB
<?php

namespace Lib;

/**
 * db 池
 * @author:dc
 * @time 2023/2/13 15:03
 * Class DbPool
 * @package Lib
 */
class DbPool {

    /**
     * @var \Lib\DbPool[]
     */
    static $instance = [];


    /**
     * @var \PDO
     */
    private $client;

    /**
     * @var
     */
    private $cid;

    public $lastTimer;

    /**
     * @return mixed
     * @author:dc
     * @time 2023/2/13 9:12
     */
    public function getClient(){
        if(!$this->client){
            $this->connect();
        }

        try {
            // 判断是否链接中
            $this->client->getAttribute(\PDO::ATTR_SERVER_INFO);
        }catch (\Throwable $e){
            $this->connect();
        }

        $this->lastTimer = time();
        return $this->client;
    }


    public function __construct($cid)
    {
        $this->cid = $cid;
        $this->connect();
    }

    /**
     * 连接sql
     * @author:dc
     * @time 2023/3/23 9:14
     */
    public function connect(){
        $this->lastTimer = time();
        try {
            $this->client = new \PDO(
                'mysql:charset=utf8mb4;dbname='.DB_DATABASE.';host='.DB_HOST.';port='.DB_PORT,
                DB_USER,
                DB_PASSWORD,
                [
                    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
                    \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8mb4'",
                    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                ]
            );
        }catch (\Throwable $e){
            logs($e->getMessage().$e->getTraceAsString());
        }
    }


    /**
     * 查询
     * @param string|array $sql
     * @return false|\PDOStatement
     * @author:dc
     * @time 2023/2/17 10:01
     */
    private function query(string|array $sql){
        if(is_array($sql)){
            list($sql,$params) = $sql;
        }else{
            $params = null;
        }

        if(APP_DEBUG) {
            $timer = microtime(true);
        }


        try {
            $query = $this->getClient()->prepare($sql);
            $ret = $query->execute($params);
        }catch (\Throwable $e){
            logs([
                $sql,$params,
                $e->getMessage(),
                $e->getTraceAsString()
            ],
                LOG_PATH.'/'.date('Y-m-d').'-sql.error.log'
            );
            $ret = false;
        }


        if(APP_DEBUG){
            $timer2  = microtime(true);

            // todo:: 记录日志,生产请注释
            $sql = '['.substr(($timer2-$timer)*1000,0,6).'ms] '.$sql;
            logs(
                $params ? [$sql,$params] : $sql,
                LOG_PATH.'/'.date('Y-m-d').'.sql.log'
            );
        }

        if($ret){
            return $query;
        }

        return false;
    }


    /**
     * 更新数据
     * @param string $table
     * @param array $data
     * @param string $where
     * @param bool $timeauto
     * @return int
     * @author:dc
     * @time 2023/2/17 14:03
     */
    public function update(string $table, array $data, string $where, $timeauto = true):int {

        if($timeauto){
            $data['updated_at'] = empty($data['updated_at']) ? date('Y-m-d H:i:s') : $data['updated_at'];
        }

        $sql = "update `{$table}` set ".dbUpdate($data). " where ".$where;

        $data = $this->getData($data);

        $query = $this->query([$sql,$data]);
        if($query){
            return $query->rowCount();
        }
        return 0;
    }


    /**
     * 在更新/插入时处理数据
     * @param $data
     * @return mixed
     * @author:dc
     * @time 2023/2/18 14:50
     */
    private function getData($data){
        // 如果存储的值是数组,就json一次
        foreach ($data as $k=>$datum){
            if(is_array($datum)){
                $data[$k] = json_encode($datum,JSON_UNESCAPED_UNICODE);
            }elseif ($datum === null){
                $data[$k] = '';
            }
        }
        return $data;
    }


    /**
     * 插入数据
     * @param string $table
     * @param array $data
     * @param bool $timeauto
     * @return int
     * @author:dc
     * @time 2023/2/17 14:04
     */
    public function insert(string $table, array $data, $timeauto = true):int {

        if($timeauto){
            $data['created_at'] = empty($data['created_at']) ? date('Y-m-d H:i:s') : $data['created_at'];
        }

        $sql = "insert into `{$table}` set ".dbUpdate($data);

        $data = $this->getData($data);

        $query = $this->query([$sql,$data]);

        if($query){
            return $this->getClient()->lastInsertId();
        }

        return 0;
    }

    /**
     * 删除语句 软删
     * @param string $table
     * @param array $where
     * @param null $upFiled
     * @return int
     * @author:dc
     * @time 2023/4/11 14:47
     */
    public function delete(string $table, array $where,$upFiled=null){

        if($upFiled){
            return $this->update($table,[$upFiled === true ? 'deleted_at' : $upFiled =>time()],$where);
        }

        $sql = "delete from `{$table}` where ".dbUpdate($where);

        $query = $this->query([$sql,$where]);

        if($query){
            return $query->rowCount();
        }

        return 0;
    }


    /**
     * 统计数量
     * @param string $sql
     * @return int
     * @author:dc
     * @time 2023/2/14 16:19
     */
    public function count(string|array $sql):int{
        $query = $this->query($sql);
        if($query){
            return $query->fetch(\PDO::FETCH_COLUMN);
        }
        return 0;
    }

    /**
     * 某个值
     * @param string|array $sql
     * @return mixed|null
     * @author:dc
     * @time 2023/2/17 11:03
     */
    public function value(string|array $sql){
        $query = $this->query($sql);
        if($query){
            return $query->fetch(\PDO::FETCH_COLUMN);
        }
        return null;
    }


    /**
     * 查询一条数据
     * @param string|array $sql
     * @return mixed|null
     * @author:dc
     * @time 2023/2/13 14:54
     */
    public function first(string|array $sql){

        $query = $this->query($sql);

        if($query){
            return $query->fetch();
        }

        return null;
    }

    /**
     * 查询列表
     * @param string|array $sql
     * @return mixed|null
     * @author:dc
     * @time 2023/2/13 14:54
     */
    public function all(string|array $sql){

        $query = $this->query($sql);

        if($query){
            return $query->fetchAll();
        }

        return null;
    }


    /**
     * 事务开启
     * @author:dc
     * @time 2023/2/17 11:35
     */
    public function transaction(){
        $this->getClient()->beginTransaction();
    }

    /**
     * 事务回滚
     * @author:dc
     * @time 2023/2/17 11:35
     */
    public function rollBack(){
        $this->getClient()->rollBack();
    }

    /**
     * 事务提交
     * @author:dc
     * @time 2023/2/17 11:35
     */
    public function commit(){
        $this->getClient()->commit();
    }



    /**
     * @param $cid
     * @return DbPool
     * @author:dc
     * @time 2023/2/13 9:39
     */
    public static function instance($cid=0){
        if(empty(static::$instance[$cid])){
            static::$instance[$cid] = new DbPool($cid);
        }
        return static::$instance[$cid];
    }


    /**
     * 结束
     */
    public function __destruct(){
        $this->close();
    }


    public function close(){
        $this->client = null;
        unset(static::$instance[$this->cid]);
    }



}