c5_labsci/zciyphp/pdo.php
2026-01-27 00:52:00 +08:00

236 lines
8.2 KiB
PHP

<?php
namespace ciy;
class pdo {
public $link;
public $isconnected;
public $error;
public $lastsql;
public $lastdata;
private $pf; //traceid全链路跟踪
private $conn;
function __construct($conn, $pf = null) {
$this->isconnected = false;
$this->error = '';
$this->pf = $pf;
$this->conn = $conn;
}
function connect() {
if ($this->isconnected)
return true;
if (isset($this->link))
$this->link = null;
try {
$timeout = 10;
if (isset($this->conn['timeout']))
$timeout = toint($this->conn['timeout']);
$charset = 'utf8mb4';
if (isset($this->conn['charset']))
$charset = $this->conn['charset'];
$persistent = false;
if (isset($this->conn['persistent']))
$persistent = (bool)$this->conn['persistent'];
$opts = array(
\PDO::ATTR_TIMEOUT => $timeout,
\PDO::ATTR_PERSISTENT => $persistent,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_SILENT,
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET {$charset}"
);
$this->link = new \PDO('mysql:host=' . $this->conn['host'] . ';dbname=' . $this->conn['name'] . ';port=' . $this->conn['port'] . ';', $this->conn['user'], $this->conn['pass'], $opts);
$this->link->query('SET SESSION sql_mode = \'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\'');
} catch (\PDOException $e) {
return $this->errsql(false, 'PDO连接失败:' . $e->GetMessage());
}
$this->isconnected = true;
return true;
}
function disconnect() {
if ($this->isconnected)
$this->link = null;
$this->isconnected = false;
return true;
}
function ping() {
if (!$this->link)
return false;
try {
$ret = $this->link->query('SELECT 1');
if ($ret === false)
return false;
} catch (\PDOException $e) {
return false;
}
return true;
}
function get($type, $query, $data) {
if (!$this->isconnected)
return false;
if ($this->pf)
$query = '/* ' . $this->pf . ' */ ' . $query;
$rs = $this->_prepare($query, $data);
if ($rs === false)
return false;
if ($type == 1) //返回全部数据
{
$retdata = $rs->fetchAll(\PDO::FETCH_ASSOC); //mysql_unbuffered_query
$rs->closeCursor();
if ($retdata === false)
return $this->errsql(array(), "表1[{$query}]数据不存在");
return $retdata;
} else if ($type == 2) { //返回单行数据
$retdata = $rs->fetch(\PDO::FETCH_ASSOC);
$rs->closeCursor();
if ($retdata === false)
return $this->errsql(null, "表2[{$query}]数据不存在");
return $retdata;
} else if ($type == 3) { //返回第一行第一列数据
$retdata = $rs->fetchColumn();
$rs->closeCursor();
if ($retdata === false)
return $this->errsql(null, "表3[{$query}]数据不存在");
return $retdata;
}
return null;
}
function update($csql, $updata) {
if (!$this->isconnected)
return false;
if (empty($csql->where))
return $this->errsql(false, 'update no where');
if (!is_array($updata))
return $this->errsql(false, 'var update not array');
if (count($updata) == 0)
return $this->errsql(0, 'update no data');
$set = '';
if (!is_array($updata))
return $this->errsql(false, 'var update not array update');
$data = array();
foreach ($updata as $key => $val) {
if (!empty($set))
$set .= ',';
if ($csql->wrapup) {
if (is_array($val))
$set .= "`{$key}`=" . $val[0];
else {
$set .= "`{$key}`=?";
$data[] = $val;
}
} else {
if (is_array($val))
$set .= $key . '=' . $val[0];
else {
$set .= $key . '=?';
$data[] = $val;
}
}
}
if ($this->execute("update {$csql->table} set {$set}" . $csql->buildwhere(), array_merge($data, $csql->tsmt)) === false)
return false;
return 1;
}
function insert($csql, $updata) {
if (!$this->isconnected)
return false;
$data = array();
if (!is_array($updata))
return $this->errsql(false, 'var update not array');
if (count($updata) == 0)
return $this->errsql(0, 'update no data');
$field = '';
$value = '';
if (!is_array($updata))
return $this->errsql(false, 'var update not array insert');
foreach ($updata as $key => $val) {
if (!empty($field))
$field .= ',';
if ($csql->wrapup)
$field .= '`' . $key . '`';
else
$field .= $key;
if (!empty($value))
$value .= ',';
if (is_array($val))
$value .= $val[0];
else {
$value .= '?';
$data[] = $val;
}
}
return $this->execute("insert into {$csql->table} ({$field}) values ({$value})", $data);
}
function insert_id() {
return $this->link->lastInsertId();
}
function execute($query, $data) {
if (!$this->isconnected)
return false;
if ($this->pf)
$query = '/* ' . $this->pf . ' */ ' . $query;
$rs = $this->_prepare($query, $data);
if ($rs === false)
return false;
$cnt = $rs->rowCount();
$rs->closeCursor();
return $cnt;
}
function begin() {
if (!$this->isconnected)
return false;
$this->link->setAttribute(\PDO::ATTR_AUTOCOMMIT, 0);
$execute = $this->link->beginTransaction();
if ($execute === false)
return $this->errsql(false, 'begin失败:' . $this->pdoerr($this->link));
return $execute;
}
function commit() {
if (!$this->isconnected)
return false;
$execute = $this->link->commit();
$this->link->setAttribute(\PDO::ATTR_AUTOCOMMIT, 1);
if ($execute === false)
return $this->errsql(false, 'commit失败:' . $this->pdoerr($this->link));
return $execute;
}
function rollback() {
if (!$this->isconnected)
return false;
$execute = $this->link->rollback();
$this->link->setAttribute(\PDO::ATTR_AUTOCOMMIT, 1);
if ($execute === false)
return $this->errsql(false, 'rollback失败:' . $this->pdoerr($this->link));
return $execute;
}
function pdoerr($pk) {
$err = $pk->errorInfo();
return $pk->errorCode() . ':' . @$err[1] . ':' . @$err[2];
}
function errsql($ret, $msg) {
$this->error = $msg;
return $ret;
}
function _prepare($query, $data) {
$this->lastsql = $query;
$this->lastdata = $data;
for ($i = 0; $i < 3; $i++) {
$rs = $this->link->prepare($query);
if ($rs === false)
return $this->errsql(false, "SQL预处理出错[{$query}]:" . $this->pdoerr($this->link));
if ($rs->execute($data) === false) {
$arr = $rs->errorInfo();
// 如果是连接断开错误,尝试重新连接
if ($arr[0] == 'HY000' && $arr[1] == 2006) {
sleep(1);
$this->isconnected = false;
if ($this->connect())
continue;
}
return $this->errsql(false, 'SQL出错:' . $arr[2] . '[' . $arr[0] . '][' . $arr[1] . ']' . $query);
}
return $rs;
}
return $this->errsql(false, 'SQL重试3次超时:' . $arr[2] . '[' . $arr[0] . '][' . $arr[1] . ']' . $query);
}
}