<?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; /** * 没有数据时 也缓存 * @var bool */ protected bool $cacheNoData = true; 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,bool $noData = true){ $this->cache = $ttl; $this->cacheNoData = $noData; 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){ return $this->getCacheData($sql,null,\PDO::FETCH_COLUMN); $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)); try { if(redis()->has($key)){ $this->cache = 0; $data = redis()->get($key,$default); if(!$this->cacheNoData){ if($data || $data === 0){ return $data; } } } }catch (\Throwable $e){ logs($e->getMessage()); } } $query = $this->query($sql); if($query){ $data = $flag? $query->fetch($flag) : $query->fetch(); if($this->cache){ try { redis()->set($key, $data, $this->cache); }catch (\Throwable $e){ logs($e->getMessage()); } $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){ if($this->cache){ try { $key = 'data:'.md5(is_string($sql) ? $sql : json_encode($sql)); if(redis()->has($key)){ $this->cache = 0; return redis()->get($key,[]); } }catch (\Throwable $e){ logs($e->getMessage()); } } $query = $this->query($sql); if($query){ $data = $query->fetchAll(); if($this->cache){ try { redis()->set($key,$data,$this->cache); }catch (\Throwable $e){ logs($e->getMessage()); } $this->cache = 0; } return $data; } return []; $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; // } }