<?php
private $connected = false;
private $lastQuery = 'nope';
private $log = array();
private $db_config = array(
'host' => 'localhost',
'port' => NULL,
'user' => 'root',
'password' => 'toor',
'db_name' => 'mysql',
'encoding' => 'utf8'
);
public function __construct($data) {
if (is_string($data)) {
$pattern = '/(\w+):?(\w+)?@(\w+):?(\w+)?\/(\w+)/';
$matches = array();
preg_match($pattern, $data, $matches);
$data = array(
'host' => $matches[3],
'port' => (integer) $matches[4],
'user' => $matches[1],
'password' => $matches[2],
'db_name' => $matches[5],
'encoding' => 'utf8'
);
} else {
$data = array();
}
$this->db_config = array_merge($this->db_config, $data);
print_r($this->db_config);
$str = $this->db_config['host'];
$str .= (!$this->db_config['port']) ? "" : ":" . $this->db_config['port'];
$this->connected = @mysqli_connect($this->db_config['host'], $this->db_config['user'], $this->db_config['password'], $this->db_config['db_name'], $this->db_config['port']);
if (!$this->connected) {
$this->handleError(mysqli_connect_error());
} else {
$dns_str = $this->db_config['user'];
$dns_str .= ":" . $this->db_config['password'];
$dns_str .= "@" . $this->db_config['host'];
$dns_str .= "/" . $this->db_config['db_name'];
$this->pushLog("Connected: " . $dns_str);
}
}
public function getRow() {
$res = $this->query(func_get_args());
if (is_a($res, 'mysqli_result')) {
$return = mysqli_fetch_array($res, MYSQLI_ASSOC);
mysqli_free_result($res);
return $return;
}
return $res;
}
public function getTable() {
$res = $this->query(func_get_args());
$table = array();
if (is_a($res, 'mysqli_result')) {
$row = mysqli_fetch_array($res, MYSQLI_ASSOC);
while ($row) {
array_push($table, $row);
$row = mysqli_fetch_array($res, MYSQLI_ASSOC);
}
return $table;
}
return $res;
}
public function getColumn() {
$res = $this->query(func_get_args());
$col = array();
if (is_a($res, 'mysqli_result')) {
$row = mysqli_fetch_array($res);
while ($row) {
array_push($col, $row[0]);
$row = mysqli_fetch_array($res);
}
return $col;
}
return $res;
}
public function getCell() {
$res = $this->query(func_get_args());
if (is_a($res, 'mysqli_result')) {
$return = mysqli_fetch_array($res);
return $return[0];
}
return $res;
}
public function query() {
$args = func_get_args();
if (sizeof($args) == 0) {
throw new InvalidArgumentException('Invalid number or arguments');
}
if (is_array($args[0])) {
$args = $args[0];
}
$inp = array_shift($args);
if (!$this->connected) {
return NULL;
}
try {
$q = !is_a($inp, 'Query') ? new Query($inp, $this->connected) : $inp;
$query = $q->parse($args);
} catch (Exception $e) {
$this->handleError($e);
return NULL;
}
$start = microtime(TRUE);
$result = mysqli_query($this->connected, $query);
$time = microtime(TRUE) - $start;
if (!is_a($result, 'mysqli_result')) {
$err = mysqli_error($this->connected);
$this->handleError($err, $query);
return NULL;
} else {
$this->lastQuery = $query;
$log = 'Complited. In ' . $time . ' microseconds. Query: "' . $query . '"';
$this->pushLog($log);
return $result;
}
}
public function getLastQuery() {
return $this->lastQuery;
}
public function getLog() {
return $this->log;
}
public function getLastMessage() {
if (sizeof($this->log) > 0) {
return $this->log[sizeof($this->log) - 1];
}
return NULL;
}
private function pushLog($event) {
array_push($this->log, $event);
}
private function handleError($error, $query = NULL) {
$result = 'Error. ';
if (is_a($error, 'Exception')) {
$result .= $error->getMessage() . ' in file: ' . $error->getFile() . ' on ' . $error->getLine() . 'line.';
} else {
$result .= (string) $error;
}
if (isset($query)) {
$result .= ' Query: ' . $query;
}
$this->pushLog($result);
}
private $query;
private $varCount = 0;
private $variable = array();
private $connected;
const DECIMAL = 'DECIMAL';
const STRING = 'STING';
const NAME = 'NAME';
const ARAY = 'ARAY';
const FLOAT = 'FLOAT';
const HASH = 'HASH';
function __construct($query, $connection = NULL) {
if (!is_string($query)) {
throw new InvalidArgumentException('String expected. ' . gettype($query) . ' given.');
}
$this->parseVariables($query);
if (is_a($connection, 'mysqli')) {
$this->connected = $connection;
}
}
public function parse() {
$query = $this->query;
$counter = 0;
$in = func_get_arg(0);
if (sizeof($in) == 0 && $this->varCount == 0) {
return $this->query;
}
$vars = $this->variable;
while (sizeof($vars) > 0) {
$currentVariable = array_shift($vars);
$currentInput = array_shift($in);
if ($currentInput === NULL) {
throw new InvalidArgumentException('Invalid number of arguments. Expected ' . $this->varCount . '.');
}
if (($currentVariable['type'] === Query::HASH || $currentVariable['type'] === Query::ARAY) &&!is_array($currentInput)) {
throw new InvalidArgumentException('Array expected. "' . gettype($currentInput) . '" is given.');
}
if (($currentVariable['type'] === Query::HASH || $currentVariable['type'] === Query::ARAY) && is_array($currentInput)) {
$paste = $this->prepareVariable($currentVariable, $currentInput);
$searchFor = '/#' . $currentVariable['id'] . '#/u';
$query = preg_replace($searchFor, $paste, $query);
$counter++;
} elseif (is_array($currentInput)) {
$c = false;
foreach ($currentInput as $input) {
if ($c) {
$currentVariable = array_shift($vars);
if ($currentVariable == NULL) {
throw new InvalidArgumentException('Query expects ' . $this->varCount . ' variables.');
}
}
if (($currentVariable['type'] === Query::HASH || $currentVariable['type'] === Query::ARAY) &&!is_array($input)) {
throw new InvalidArgumentException('Array expected. "' . gettype($input) . '" is given.');
}
$paste = $this->prepareVariable($currentVariable, $input);
$searchFor = '/#' . $currentVariable['id'] . '#/u';
$query = preg_replace($searchFor, $paste, $query);
$counter++;
$c = true;
}
} else {
$paste = $this->prepareVariable($currentVariable, $currentInput);
$searchFor = '/#' . $currentVariable['id'] . '#/u';
$query = preg_replace($searchFor, $paste, $query);
$counter++;
}
}
if ($counter != $this->varCount) {
throw new InvalidArgumentException('Invalid number of variables is given.d');
}
return $query;
}
private function parseVariables($string) {
$pattern = '/%([DFSNHA])({([^{}]+)})?/u';
$array = preg_split($pattern, $string);
$matches = array();
preg_match_all($pattern, $string, $matches);
$result = "";
$counter = 0;
foreach ($array as $key => $value) {
if (isset($matches[1][$key])) {
switch ($matches[1][$key]) {
case 'F':
$type = Query::FLOAT;
break;
case 'D':
$type = Query::DECIMAL;
break;
case 'N':
$type = Query::NAME;
break;
case 'A':
$type = Query::ARAY;
break;
case 'H':
$type = Query::HASH;
break;
default:
$type = Query::STRING;
}
$this->variable[$counter]['type'] = $type;
$this->variable[$counter]['regexp'] = $matches[3][$key];
$this->variable[$counter]['id'] = $counter;
$result .= $value . '#' . $counter . '#';
$counter++;
} else {
$result .= $value;
}
}
$this->varCount = $counter;
$this->query = $result;
}
private function prepareVariable($field, $value) {
if ($value === NULL) {
return NULL;
}
if ($field['regexp'] != NULL) {
if (!preg_match($field['regexp'], $value)) {
throw new InvalidArgumentException('Argument: "' . $value . '" Doesn\'t matches: ' . $field['regexp']);
}
}
switch ($field['type']) {
case Query::DECIMAL:
$result = $this->prepareDecimal($value);
break;
case Query::STRING:
$result = $this->prepareSting($value);
break;
case Query::NAME:
$result = $this->prepareName($value);
break;
case Query::ARAY:
if (!is_array($value)) {
throw new InvalidArgumentException('Array expected. ' . gettype($value) . ' is given.');
}
$result = '(';
while (sizeof($value) > 1) {
$val = $this->prepareUnknown(array_shift($value));
$result .= $val . ', ';
}
$val = $this->prepareUnknown(array_shift($value));
$result .= $val . ')';
break;
case Query::FLOAT:
$result = $this->prepareFloat($value);
break;
case Query::HASH:
if (!is_array($value)) {
throw new InvalidArgumentException('Array expected. ' . gettype($value) . ' is given.');
}
$result = '';
if (sizeof($value) > 0) {
foreach ($value as $key => $valu) {
$key = $this->prepareName($key);
$valu = $this->prepareUnknown($valu);
$result .= $key . '=' . $valu . ', ';
}
$result = substr($result, 0, strlen($result) - 2);
}
break;
default: $result = NULL;
}
return $result;
}
private function prepareUnknown($unk) {
if (is_integer($unk)) {
return $this->prepareDecimal($unk);
} elseif (is_float($unk)) {
return $this->prepareFloat($unk);
}
return $this->prepareSting($unk);
}
private function prepareSting($str) {
if (!is_string($str)) {
throw new InvalidArgumentException('String expected. ' . gettype($str) . ' is given.');
}
$str = stripslashes($str);
if (isset($this->connected)) {
$str = mysqli_real_escape_string($this->connected, $str);
} else {
$str = mysql_real_escape_string($str);
}
$result = "'" . $str . "'";
return $result;
}
private function prepareFloat($flo) {
if (!is_numeric($flo)) {
throw new InvalidArgumentException('Float expected. ' . gettype($flo) . ' is given.');
}
return (float) $flo;
}
private function prepareDecimal($dec) {
if (!is_numeric($dec)) {
throw new InvalidArgumentException('Decimal expected. ' . gettype($dec) . ' is given.');
}
return round($dec);
}
private function prepareName($name) {
if (!is_string($name)) {
throw new InvalidArgumentException('String expected. ' . gettype($name) . ' is given.');
}
$name = stripslashes($name);
if (isset($this->connected)) {
$str = mysqli_real_escape_string($this->connected, $name);
} else {
$str = mysql_real_escape_string($name);
}
if (strlen($name) > 30) {
throw new LengthException('Length of name should be less then 30 symbols');
}
return '`' . $name . '`';
}