php pdo類 防注入,事務,多庫自動選擇,鏈式操作
阿新 • • 發佈:2019-07-13
因為某些原因目前業務不用框架開發,自己寫了一個pdo類實現防注入,事務等,後續還會繼續完善
<?php
/**
* Created by PhpStorm.
* User: ywx
* Date: 2019/7/10
* Time: 14:57
*/
class Db
{
private $conn;
private $sql = [
'where' => null,
'wheresql' => null,
'orderBy' => null,
'limit' => null,
'up' => null,
'ins' => null,
];
private $type;
public function __construct( $data = [])
{
if($data){
$this->_setDbDrive($data);
}
}
private function _setDbDrive($dbConf){
$dns = 'mysql:host='.$dbConf['DB_IP'].';dbname='.$dbConf['DB_NAME'].';charset=utf8mb4';
try {
$db = new PDO($dns,$dbConf['DB_USER'],$dbConf['DB_PASS']);
} catch(PDOException $e) {
die('Could not connect to the database:<br/>' . $e);
}
$this->conn[$dbConf['name']] = $db;
}
public function table($tablename) {
//獲取表庫資訊
$db_info = $this->_getDBIP($tablename);
$this->sql = [];//重置快取
$this->type = $db_info['name'];
if(!isset($this->conn[$db_info['name']])){
$this->_setDbDrive($db_info);
}
$this->tablename = $tablename;
return $this;
}
public function select($fields = '*') {
$querySql = sprintf("SELECT %s FROM %s", $fields, $this->tablename);
if(!empty($this->sql['where'])) {
$querySql .= ' WHERE ' . $this->sql['wheresql'];
}
if(!empty($this->sql['orderBy'])) {
$querySql .= ' ORDER BY ' . $this->sql['orderBy'];
}
if(!empty($this->sql['limit'])) {
$querySql .= ' LIMIT ' . $this->sql['limit'];
}
return $this->_query($querySql);
}
public function find($fields = '*') {
$result = $this->select($fields);
return isset($result[0]) ? $result[0] : null;
}
public function insert($data) {
foreach ($data as $key => &$value) {
$value = addslashes($value);
}
$keys = "`".implode('`,`', array_keys($data))."`";
$values = ":i".implode(", :i", array_keys($data));
$this->sql['ins'] = $data;
$querySql = sprintf("INSERT INTO %s ( %s ) VALUES ( %s )", $this->tablename, $keys, $values);
return $this->_query($querySql);
}
public function delete() {
$querySql = sprintf("DELETE FROM %s WHERE ( %s )", $this->tablename, $this->sql['wheresql']);
return $this->_query($querySql);
}
/**
* 傳入陣列 ['apid'=>['+',15],'bpid'=>105] 目前二位陣列僅支援 加減
* @param $data
* @return mixed
*/
public function update($data) {
$updateFields = [];
foreach ($data as $key => $value) {
if(!is_array($value)){
$updateFields[] = "`$key`=:u{$key} ";
}else{
$updateFields[] = "`$key`= `{$key}` {$value[0]} {$value[1]}";
unset($data[$key]);
}
}
$this->sql['up'] = $data;
$updateFields = implode(',', $updateFields);
$querySql = sprintf("UPDATE %s SET %s", $this->tablename, $updateFields);
if(!empty($this->sql['where'])) {
$querySql .= ' WHERE ' . $this->sql['wheresql'];
}
return $this->_query($querySql);
}
private function _query($querySql) {
$querystr = strtolower(trim(substr($querySql,0,6)));
$stmt = $this->conn[$this->type]->prepare($querySql);
//繫結引數 where
if($this->sql['wheresql']){
foreach($this->sql['where'] as $k=>$v){
if(!is_array($v)){
$val = $v;
}else{
$val = $v[1];
}
$stmt->bindValue('w'.$k,addslashes($val));
}
}
//update
if($this->sql['up']){
foreach($this->sql['up'] as $k=>$v){
$stmt->bindValue('u'.$k,trim($v,'\''));
}
}
//install
if($this->sql['ins']){
foreach($this->sql['ins'] as $k=>$v){
$stmt->bindValue('i'.$k,addslashes($v));
}
}
$ret = $stmt->execute();
$this->sql = [];
if(!$ret) var_dump($stmt->errorInfo());
if($querystr == 'select') {
$retData = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $retData;
}elseif($ret && $querystr == 'insert') {
return $this->conn[$this->type]->lastInsertId();
}else{
return $ret;
}
}
public function limit($limit, $limitCount = null) {
if(!$limitCount) {
$this->sql['limit'] = $limit;
}else{
$this->sql['limit'] = $limit .','. $limitCount;
}
return $this;
}
public function orderBy($orderBy) {
$this->sql['orderBy'] = $orderBy;
return $this;
}
public function where($where) {
if(!is_array($where)) {
return null;
}
$crondsArr = [];
foreach ($where as $key => $value) {
$fieldValue = $value;
if(is_array($fieldValue)) {
$crondsArr[] = "`$key` ".$fieldValue[0]. ' :w' . $key;
}else{
$crondsArr[] = "`$key`=:w{$key}";
}
}
$this->sql['wheresql'] = implode(' AND ', $crondsArr);
$this->sql['where'] = $where;
return $this;
}
public function close() {
return $this->conn = null;
}
//開啟事務
public function startTrans(){
if(empty($this->conn[$this->type])){
exit();
}
$this->conn[$this->type]->beginTransaction();
}
//提交事務
public function dbCommit(){
if(empty($this->conn[$this->type])){
exit();
}
$this->conn[$this->type]->commit();
}
//回滾事務
public function dbRollBack(){
if(empty($this->conn[$this->type])){
exit();
}
$this->conn[$this->type]->rollBack();
}
/**
* 原生查詢
* @param $querySql
* @return mixed
*/
public function query($querySql) {
$querystr = strtolower(trim(substr($querySql,0,6)));
$stmt = $this->conn[$this->type]->prepare($querySql);
$ret = $stmt->execute();
$this->sql = [];
if(!$ret) var_dump($stmt->errorInfo());
if($querystr == 'select') {
$retData = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $retData;
}elseif($ret && $querystr == 'insert') {
return $this->conn[$this->type]->lastInsertId();
}else{
return $ret;
}
}
private function _getDBIP($tableName){
switch($tableName){
default:
return array(
'name' =>'server',
'DB_IP' => DB_IP,
'DB_NAME' => DB_NAME,
'DB_USER' => DB_USER,
'DB_PASS' => DB_PASS,
);
break;
case 'xxxx':
case 'xxxx':
return array(
'name' =>'master',
'DB_IP' => DB_MAS_IP,
'DB_NAME' => DB_MAS_NAME,
'DB_USER' => DB_MAS_USER,
'DB_PASS' => DB_MAS_PASS,
);
break;
case 'xxx':
case 'xxx':
return array(
'name' =>'manage',
'DB_IP' => DB_MNG_IP,
'DB_NAME' => DB_MNG_NAME,
'DB_USER' => DB_MNG_USER,
'DB_PASS' => DB_MNG_PASS,
);
break;
// LOGS
case 'xxx':
return array(
'name' =>'log',
'DB_IP' => DB_LOG_IP,
'DB_NAME' => DB_LOG_NAME,
'DB_USER' => DB_LOG_USER,
'DB_PASS' => DB_LOG_PASS,
);
break;
}
}
}