236 lines
8.2 KiB
PHP
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);
|
|
}
|
|
}
|