sql = new mysqli('p:'.$server,$user,$pass,$db) or die('Unable to connect to mysql'); self::$connections[] = $sql; } public function __destruct(){ $this->sql->rollback(); $this->sql->close(); foreach($this->queries as $query){ unset($query); } self::$connections = array_diff(self::$connections, [$this]); } public function __invoke(){ return $this->sql; } public function __get($name){ switch($name){ case 'error': return $this->sql->error; break; case 'insert_id': return $this->sql->insert_id; break; } } /** * Returns a Query object based on inputs * * @method query * @param {String} sql The sql expression to run * @param {String=null} [types] A string containing all the types of arguments being passed * @param {Mixed} [bindings]* The bindings to use in the sql statement * @return {Query} Returns the query object */ public function query(...$args){ return new Query(...array_merge([$this], $args)); } public function escape($s){ return $this->sql->escape_string($s); } public function charset($charset){ return $this->sql->set_charset($charset); } public static function make_referenced(&$arr){ $refs = []; foreach($arr as $key => $value){ $refs[$key] = &$arr[$key]; } return $refs; } public static function shutdown(){ foreach(self::$connections as $sql){ unset($sql); } } } /** * Query class. Returned by SQL::query() * * @class Query * @constructor */ class Query { private $query; private $sql; private $_result = false; public function __construct($sql, $source, $types=null, ...$args){ $sql->queries[] = $this; $args = array_merge([$types], $args); $this->sql = $sql(); $this->query = $this->sql->prepare($source); if(!is_null($types)){ if(!$this->query->bind_param(...SQL::make_referenced($args))){ throw new Exception("Unable to bind parameter {$this->query->error}"); } } } public function __destruct(){ if($this->_result){ $this->_result = false; $this->query->free_result(); } if($this->query){ $this->query->close(); } $sql->queries = array_diff($sql->queries, [$this]); } public function __invoke(){ return $this->query; } public function execute(){ if($this->query){ $this->query->free_result(); $this->_result = false; $this->query->reset(); $r = $this->query->execute(); $this->sql->commit(); return $r; }else{ return false; } } public function each_assoc(callable $fn){ if($this->query){ $r = $this->results; while($row = $r->fetch_assoc()){ $fn($row); } }else{ return false; } } public function each_num(callable $fn){ if($this->query){ $r = $this->results; while($row = $r->fetch_num()){ $fn($row); } }else{ return false; } } public function __get($name){ switch($name){ /** * Returns the mysqli::results object for the * query * * @property results * @type {mysqli::results} * @public */ case 'results': if(!$this->_result && $this->query){ $this->execute(); $this->_result = $this->query->get_result(); $this->query->close(); } return $this->_result; break; /** * Returns an associative array of the query resulsts * * @property assoc_results * @type {Array} * @public */ /** * Returns an associative array of the query resulsts * * @property resulsts_assoc * @type {Array} * @public */ case 'assoc_results':case 'results_assoc': if($this->query){ $a = []; $r = $this->results; while($row = $r->fetch_assoc()){ array_push($a,$row); } return $a; }else{ return false; } break; /** * Returns a numbered array of the query results * * @property num_results * @type {Array} * @public */ /** * Returns a numbered array of the query results * * @property resulsts_num * @type {Array} * @public */ case 'num_results':case 'results_num': if($this->query){ $a = []; $r = $this->results; while($row = $r->fetch_num()){ array_push($a,$row); } return $a; }else{ return false; } break; case 'assoc_result':case 'result_assoc': if($this->query){ $r = $this->results; return $r?$r->fetch_assoc():false; }else{ return false; } break; case 'num_result':case 'result_num': if($this->query){ $r = $this->results; return $r?$r->fetch_num():false; }else{ return false; } break; case 'insert_id': return $this->sql->insert_id; break; case 'affected_rows': return $this->query->affected_rows; break; } } } register_shutdown_function(function(){ SQL::shutdown(); }); ?>