DbQuery.php 8.0 KB
<?php

namespace Lib;

/**
 * db 查询
 * @author:dc
 * @time 2023/2/13 15:03
 * Class DbPool
 * @package Lib
 */
trait DbQuery {

    /**
     * @var \PDO|null
     */
    protected $client;

    /**
     * 是否抛出异常
     * @var bool
     */
    protected $isThrow = false;

    /**
     * 是否缓存
     * @var int
     */
    protected int $cache = 0;


    public function getClient()
    {
        return $this->client;
    }

    /**
     * @return $this
     * @author:dc
     * @time 2024/7/24 9:09
     */
    public function throw(){
        $this->isThrow = true;
        return $this;
    }

    /**
     * 是否缓存结果
     * @param int $ttl
     * @return $this
     * @author:dc
     * @time 2024/8/14 14:04
     */
    public function cache(int $ttl){
        $this->cache = $ttl;
        return $this;
    }


    /**
     * 查询
     * @param string|array $sql
     * @return false|\PDOStatement
     * @author:dc
     * @time 2023/2/17 10:01
     */
    public 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){
            if($this->isThrow){
                $this->isThrow = false;
                throw new DbException($e->getMessage(),$sql,$params,$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
     */
    public 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($this->create($table,  $data, $timeauto)){
            return $this->getClient()->lastInsertId();
        }

        return 0;
    }

    /**
     * 插入数据
     * @param string $table
     * @param array $data
     * @param bool $timeauto
     * @return int
     * @author:dc
     * @time 2023/2/17 14:04
     */
    public function create(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 true;
        }

        return false;
    }

    /**
     * 删除语句 软删
     * @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 ".dbWhere($where);

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

        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{
        return (int) $this->getCacheData($sql,0,\PDO::FETCH_COLUMN);
    }

    /**
     * 某个值
     * @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 $sql
     * @param string $default
     * @param null $flag
     * @return int|mixed|string
     * @throws DbException
     * @author:dc
     * @time 2024/9/23 11:57
     */
    private function getCacheData($sql, $default = '', $flag = null){
        if($this->cache){
            $key = 'data:'.md5(is_string($sql) ? $sql : json_encode($sql));
            if(redis()->has($key)){
                $this->cache = 0;
                return redis()->get($key,$default);
            }
        }
        $query = $this->query($sql);
        if($query){
            $data = $flag? $query->fetch($flag) :  $query->fetch();
            if($this->cache){
                redis()->set($key,$data,$this->cache);
                $this->cache = 0;
            }
            return $data;
        }

        return $default;
    }

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

        return $this->getCacheData($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 [];
    }


    /**
     * 事务开启
     * @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();
    }


    /**
     * 验证是否正常连接
     * @return bool
     * @author:dc
     * @time 2024/4/10 10:09
     */
    public function ping(){
        try {
            $query = $this->getClient()->query("select 200;");
            if($query->fetchColumn() == 200){
                return true;
            }
        }catch (\Throwable $e){
            return false;
        }

        return false;
    }


}