<?php
ini_set('display_errors', true);
final class DB {
private static $db;
public static function getInstance(): PDO {
if(!self::$db instanceof PDO) {
new self();
}
return self::$db;
}
private function __clone() {}
private function __construct() {
$config = parse_ini_file('./db.ini');
$dsn = sprintf('mysql:localhost=%s;dbname=%s;port=%d;charset=%s', $config['host'], $config['dbname'], $config['port'], $config['charset']);
try{
self::$db = new PDO($dsn, $config['user'], $config['password']);
}catch(PDOException $e) {
exit($e->getMessage());
}
}
}
class Statement {
private static $statement;
private $state;
private function __construct(PDO $db, string $sql) {
$this->state = $db->prepare($sql);
}
public static function getInstance(PDO $db, string $sql) {
if(!self::$statement instanceof Statement) {
self::$statement = new self($db, $sql);
}
return self::$statement;
}
public function bindValue($key, $val) {
return $this->state->bindValue($key, $val);
}
public function bindParam($key, $val) {
return $this->state->bindParam($key, $val);
}
public function execute() {
return $this->state->execute();
}
public function fetchOne() {
return $this->state->fetch(PDO::FETCH_ASSOC);
}
public function fetchAll() {
return $this->state->fetchAll(PDO::FETCH_ASSOC);
}
public function fetchColumn(int $index = null) {
return $this->state->fetchColumn($index);
}
public function resetQuery() {
return $this->state->closeCursor();
}
public function effectRow() {
return $this->state->rowCount();
}
public function errorReason() {
return $this->state->errorInfo()[2];
}
}
/**建立方法的抽象基类
* Class Base
*/
abstract class Base {
protected $db;
protected $statement;
public function __construct(string $sql) {
$this->db = DB::getInstance();
$this->statement = Statement::getInstance($this->db, $sql);
}
protected function exec() {
return $this->statement->execute() ? true: $this->statement->errorReason() ?? 'SQL语句有误';
}
public function bindValue($key = null, $val = null) {
if(func_num_args() === 0 || (!is_array($key) && !$val)) {
return $this;
} else if(is_array($key)) {
foreach($key as $k => $v) {
$this->statement->bindValue($k, $v);
}
} else {
$this->statement->bindValue($key, $val);
}
return $this;
}
public function bindParam($key = null, $val = null) {
if(func_num_args() === 0 || (!is_array($key) && !$val)) {
return $this;
} else if(is_array($key)) {
foreach($key as $k => $v) {
$this->statement->bindParam($k, $v);
}
} else {
$this->statement->bindParam($key, $val);
}
return $this;
}
public static function getDB(): PDO {
return DB::getInstance();
}
}
class Query extends Base{
private function queryRes(bool $is_all = false) {
$res = $this->exec();
if($res === true) {
$data = $is_all? $this->statement->fetchAll(): $this->statement->fetchOne();
return $data === false? []: $data;
}
return $res;
}
public function one() {
return $this->queryRes(false);
}
public function all() {
return $this->queryRes(true);
}
public function fetchColumn($index = 0) {
$res = $this->exec();
if($res) {
$data = $this->statement->fetchColumn($index);
return $data === false? '': $data;
}
return $res;
}
public function __destruct() {
$this->statement->resetQuery();
}
}
class Operate extends Base{
public function execute() {
$res = $this->exec();
if($res === true) {
return $this->statement->effectRow();
}
throw new PDOException($res);
}
public static function beginTransaction($fn) {
if(!$fn) {
return false;
}
self::getDB()->beginTransaction();
try{
call_user_func($fn);
return self::getDB()->commit()? true: false;
}catch(PDOException $e) {
self::getDB()->rollBack();
throw $e;
}
}
//注意:如果在事务中进行调用,那么就有可能获取不到
public static function lastInsertId() {
return self::getDB()->lastInsertId();
}
}
//$res = (new Query('SELECT `u`.`user`, `temp`.`pwd` FROM `user` AS `u` LEFT JOIN (SELECT `id`, `pwd` FROM `user`) AS `temp` ON `temp`.`id` = `u`.`id` WHERE `u`.`id` > :id'))->bindValue(':id', 3)->all();
//var_dump($res);
//$res = (new Query('SELECT * FROM `user`'))->all();
//var_dump($res);
//$res = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
// ':user' => 'are you ok???',
// ':id' => 1
//])->execute();
//var_dump($res);
//Operate::getDB()->beginTransaction();
//try{
// $res1 = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
// ':user' => 'tt',
// ':id' => 1
// ])->execute();
// $res2 = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
// ':user' => 'tt',
// ':id' => 2
// ])->execute();
// if($res1 === true && $res2 === true) {
// Operate::getDB()->commit();
// }
//}catch(PDOException $e) {
// Operate::getDB()->rollBack();
// throw $e;
//}
//$res1 = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
// ':user' => 'tt',
// ':id' => 1
//])->execute();
//$res2 = (new Operate('UPDATE `user` SET `user` = :user WHERE `id` = :id'))->bindValue([
// ':user' => 'tt',
// ':id' => 2
//])->execute();
//var_dump($res1);
//var_dump($res2);
//$res = Operate::beginTransaction(function() {
// (new Operate('INSERT INTO `user` (`user`, `pwd`) VALUES (:user, :pwd)'))->bindValue([
// ':user' => 'wakaka',
// ':pwd' => 'nono'
// ])->execute();
//});
//var_dump($res);
(new Operate('INSERT INTO `user` (`user`, `pwd`) VALUES (:user, :pwd)'))->bindValue([
':user' => 'wakaka',
':pwd' => 'nono'
])->execute();
var_dump(Operate::lastInsertId());
?>