711 lines
15 KiB
PHP
711 lines
15 KiB
PHP
<?php
|
||
|
||
/**
|
||
*
|
||
* Interfejs polaczenia z baza
|
||
*
|
||
*/
|
||
interface DBConnection {
|
||
|
||
public function Prepare($query);
|
||
|
||
public function Execute($query);
|
||
}
|
||
|
||
/**
|
||
* Interfejs danych w bazie
|
||
*
|
||
*/
|
||
interface DBStatement {
|
||
|
||
public function Execute();
|
||
|
||
public function BindParam($key, $value);
|
||
|
||
public function FetchRow();
|
||
|
||
public function FetchAssoc();
|
||
|
||
public function FetchAllAssoc();
|
||
}
|
||
|
||
/**
|
||
* Klasa do obslugi bazy mysql
|
||
*
|
||
*/
|
||
class DBMysql implements DBConnection {
|
||
|
||
protected $user;
|
||
protected $pass;
|
||
protected $dbHost;
|
||
protected $dbName;
|
||
protected $dbh;
|
||
private $query;
|
||
protected $characterset = 'utf8';
|
||
|
||
/**
|
||
* Konstruktor klasy
|
||
*
|
||
* @param string $user
|
||
* @param string $pass
|
||
* @param string $dbHost
|
||
* @param string $dbName
|
||
*/
|
||
public function __construct($user, $pass, $dbHost, $dbName) {
|
||
$this->user = $user;
|
||
$this->pass = $pass;
|
||
$this->dbHost = $dbHost;
|
||
$this->dbName = $dbName;
|
||
}
|
||
|
||
/* Nawiazywanie polaczenia z baza */
|
||
|
||
public function Connect($method = null) {
|
||
|
||
if (!Core::GetAppSafeMode()) {
|
||
try { //echo $method;
|
||
$this->DbConnect();
|
||
//Utils::ArrayDisplay($this);
|
||
$this->SelectDb();
|
||
$this->SetCharacterset();
|
||
} catch (Exception $e) {
|
||
MFLog::Fatal("Line: " . $e->getLine() . " Message: " . $e->getMessage() . " Referer: " . getenv('HTTP_REFERER'));
|
||
MFLog::Error("Switching app to safe mode");
|
||
Core::SetAppSafeMode();
|
||
}
|
||
}
|
||
}
|
||
|
||
protected function DbConnect() {
|
||
//echo"konekt";
|
||
Profiler::log('mysqlStart', '', microtime());
|
||
$this->dbh = @new mysqli($this->dbHost, $this->user, $this->pass, $this->dbName);
|
||
if ($this->dbh->connect_errno) {
|
||
throw new MysqlException("Failed to connect to MySQL: (" . $this->dbh->connect_errno . ") " . $this->dbh->connect_error, $this->dbh->connect_errno);
|
||
}
|
||
}
|
||
|
||
protected function SelectDb() {
|
||
if (!mysqli_select_db($this->dbh, $this->dbName)) {
|
||
throw new MysqlException('Cannot select database!');
|
||
}
|
||
}
|
||
|
||
protected function SetCharacterset() {
|
||
mysqli_query($this->dbh, "SET CHARACTER SET " . $this->characterset);
|
||
mysqli_query($this->dbh, "SET NAMES '" . $this->characterset . "'");
|
||
mysqli_query($this->dbh, "SET CHARACTER_SET_CLIENT = " . $this->characterset);
|
||
mysqli_query($this->dbh, "SET character_set_results = " . $this->characterset);
|
||
mysqli_query($this->dbh, "SET character_set_connection = " . $this->characterset);
|
||
}
|
||
|
||
public function Escape($string) {
|
||
|
||
|
||
$return = mysqli_real_escape_string($this->dbh, $string);
|
||
|
||
return $return;
|
||
}
|
||
|
||
/* Wykonanie zapytania */
|
||
|
||
public function Execute($query) {
|
||
|
||
if (!$this->dbh) {
|
||
$this->Connect(__METHOD__);
|
||
}
|
||
MFLog::Debug($query);
|
||
$ret = 'unexecuted';
|
||
if ($this->dbh) {
|
||
$startTime = microtime();
|
||
$ret = $this->dbh->query($query);
|
||
$endTime = microtime();
|
||
$deltaTime = (int)$endTime - (int)$startTime;
|
||
Profiler::log('mysql', $query, abs($deltaTime));
|
||
}
|
||
if (!$ret && $ret != 'unexecuted') {
|
||
throw new MysqlException(mysqli_error($this->dbh) . $query);
|
||
} else {
|
||
$this->setQuery($query);
|
||
$stmt = new DBMysqlStatement($this);
|
||
$stmt->result = $ret;
|
||
return $stmt;
|
||
}
|
||
}
|
||
|
||
/* Przygotowanie zapytania zwraca obiekt klasy DBMysqlStatement */
|
||
|
||
public function Prepare($query) {
|
||
if (!$this->dbh) {
|
||
//$this->Connect(__METHOD__);
|
||
}
|
||
$this->setQuery($query);
|
||
return new DBMysqlStatement($this);
|
||
}
|
||
|
||
/**
|
||
* Rozpoczyna transakcje
|
||
*
|
||
*/
|
||
public function BeginTransaction() {
|
||
if (!$this->dbh) {
|
||
$this->Connect(__METHOD__);
|
||
}
|
||
@mysqli_query($this->dbh, "START TRANSACTION ");
|
||
}
|
||
|
||
/**
|
||
* Zartwierdza transakcje
|
||
*
|
||
*/
|
||
public function CommitTransaction() {
|
||
if (!$this->dbh) {
|
||
$this->Connect(__METHOD__);
|
||
}
|
||
@mysqli_query($this->dbh,"COMMIT");
|
||
}
|
||
|
||
/**
|
||
* Wycofuje transakcje
|
||
*
|
||
*/
|
||
public function Rollback() {
|
||
if (!$this->dbh) {
|
||
$this->Connect(__METHOD__);
|
||
}
|
||
@mysqli_query($this->dbh,"ROLLBACK");
|
||
}
|
||
|
||
/**
|
||
* Destruktor zamykajacy polaczenie
|
||
*
|
||
*/
|
||
public function __destruct() {
|
||
if (isset($this->dbh) && is_resource($this->dbh)) {
|
||
|
||
Profiler::log('mysqlEnd', '', microtime());
|
||
}
|
||
}
|
||
|
||
public function GetDbh() {
|
||
return $this->dbh;
|
||
}
|
||
|
||
public function getQuery() {
|
||
return $this->query;
|
||
}
|
||
|
||
public function setQuery($query) {
|
||
$this->query = $query;
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Klasa implementujaca interfejs DBStatement dla mysqla
|
||
*
|
||
*/
|
||
class DBMysqlStatement implements DBStatement {
|
||
|
||
public $result;
|
||
public $binds;
|
||
public $query;
|
||
public $dbh;
|
||
private $cacheTime = 30;
|
||
private $cacheFile;
|
||
private $cachePath = DBCACHE_PATH;
|
||
private $cacheEnable = DBCACHE_ENABLE;
|
||
private $cacheQuery = false;
|
||
private $dbMysql;
|
||
|
||
/**
|
||
* KOnstruktor klasy
|
||
*
|
||
* @param mysql $dbh
|
||
* @param string $query
|
||
*/
|
||
public function __construct(DBMysql $dbMysql) {
|
||
$this->query = $dbMysql->getQuery();
|
||
$this->dbh = $dbMysql->GetDbh();
|
||
$this->dbMysql = $dbMysql;
|
||
if (!$this->dbh) {
|
||
// $this->dbMysql->Connect();
|
||
//throw new MysqlException("No db connection");
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Zwraca tresc zapytania
|
||
*
|
||
* @return unknown
|
||
*/
|
||
public function GetQuery() {
|
||
return $this->query;
|
||
}
|
||
|
||
/* Zamienia zmienne w zapytaniu na podane wartosci */
|
||
|
||
public function BindParam($ph, $pv) {
|
||
$this->binds[$ph] = $pv;
|
||
return $this;
|
||
}
|
||
|
||
/* Wykonanie zapytania */
|
||
|
||
public function Execute($q = null) {
|
||
//echo $q.":";
|
||
//var_dump($this->CacheCheck());
|
||
//var_dump(Core::GetAppSafeMode());
|
||
if (!$this->CacheCheck() && !Core::GetAppSafeMode()) {
|
||
//echo"qq";
|
||
if (!$this->dbh) {
|
||
$this->dbMysql->Connect(__METHOD__ . $this->query);
|
||
}
|
||
$binds = func_get_args();
|
||
foreach ($binds as $index => $name) {
|
||
$this->binds[$index + 1] = $name;
|
||
}
|
||
$cnt = count($binds);
|
||
$query = $this->query;
|
||
|
||
|
||
$binds = func_get_args();
|
||
foreach ($binds as $index => $name) {
|
||
$this->binds[$index + 1] = $name;
|
||
}
|
||
$cnt = count($binds);
|
||
$query = $this->query;
|
||
|
||
//Utils::ArrayDisplay($query);
|
||
|
||
if(is_countable($this->binds)) {
|
||
if (count($this->binds) > 0) {
|
||
foreach ($this->binds as $ph => $pv) {
|
||
// $query = str_replace(":$ph", "'".mysqli_escape_string($pv)."'", $query);
|
||
|
||
$query = str_replace(":$ph", '\'' . mysqli_real_escape_string($this->dbh, $pv) . '\'', $query);
|
||
}
|
||
}//echo ">>".$query;
|
||
}
|
||
MFLog::Debug(__FUNCTION__ . ' query: ' . $query);
|
||
|
||
|
||
$startTime = microtime();
|
||
$this->result = $this->dbh->query($query);
|
||
$endTime = microtime();
|
||
$deltaTime = (int)$endTime - (int)$startTime;
|
||
Profiler::log('mysql', $query, abs($deltaTime));
|
||
|
||
|
||
if (!$this->result) {
|
||
throw new MysqlException($query . "<br /><br />" . mysqli_error($this->dbh));
|
||
}
|
||
}
|
||
|
||
return $this;
|
||
}
|
||
|
||
/* Zwraca wiersz */
|
||
|
||
public function FetchRow() {
|
||
if (!$this->result) {
|
||
throw new MysqlException("Query failed");
|
||
}
|
||
$this->SetCacheFile($this->query . 'FetchRow');
|
||
|
||
if ($this->cacheQuery == false) {
|
||
if (!$this->result)
|
||
$this->Execute();
|
||
|
||
$result = mysqli_fetch_row($this->result);
|
||
mysqli_free_result($this->result);
|
||
}
|
||
|
||
else if ($this->cacheQuery == true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
|
||
if (!$this->result)
|
||
$this->Execute();
|
||
|
||
$result = mysqli_fetch_row($this->result);
|
||
mysqli_free_result($this->result);
|
||
$this->CacheWrite($result);
|
||
} else {
|
||
$result = $this->CacheRead();
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/* Zwraca wiersz jako tablice asocjacyjna */
|
||
|
||
public function FetchAssoc() {
|
||
$this->SetCacheFile($this->query . 'FetchAssoc');
|
||
|
||
if ($this->cacheQuery == false) {
|
||
//$this->dbMysql->Connect();
|
||
if (!$this->result)
|
||
$this->Execute();
|
||
//var_dump($this->result);
|
||
//Utils::ArrayDisplay($this);
|
||
if (!($this->result instanceof mysqli_result)) {
|
||
return false;
|
||
}
|
||
$result = \mysqli_fetch_assoc($this->result);
|
||
}
|
||
|
||
else if (($this->cacheQuery == true && !$this->CacheCheck() && !Core::GetAppSafeMode())) {
|
||
|
||
//$this->dbMysql->Connect(__METHOD__);
|
||
$this->Execute();
|
||
if (!($this->result instanceof mysqli_result)) {
|
||
return false;
|
||
}
|
||
$result = mysqli_fetch_assoc($this->result);
|
||
$this->CacheWrite($result);
|
||
} else {
|
||
$result = $this->CacheRead();
|
||
}
|
||
//Utils::ArrayDisplay($this->dbh);
|
||
return $result;
|
||
}
|
||
|
||
/* Zwraca ca<63>y wynik jako tablica asocjacyjna */
|
||
|
||
public function FetchAllAssoc() {
|
||
$this->SetCacheFile($this->query . 'FetchAllAssoc');
|
||
//Utils::ArrayDisplay($this);
|
||
if ($this->cacheQuery == false) {
|
||
$result = array();
|
||
//$this->Execute();
|
||
while ($row = $this->fetchAssoc()) {
|
||
$result[] = $row;
|
||
}
|
||
|
||
} else if ($this->cacheQuery == true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
|
||
$result = array();
|
||
$this->cacheQuery = false;
|
||
while ($row = $this->fetchAssoc()) {
|
||
$result[] = $row;
|
||
}
|
||
$this->SetCacheFile($this->query . 'FetchAllAssoc');
|
||
$this->CacheWrite($result);
|
||
} else {
|
||
$result = $this->CacheRead();
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/* Zwraca ca<63>y wynik jako tablica asocjacyjna */
|
||
|
||
public function FetchAllRow() {
|
||
$this->SetCacheFile($this->query . 'FetchAllRow');
|
||
|
||
|
||
|
||
if ($this->cacheQuery == false) {
|
||
$result = array();
|
||
|
||
while ($row = $this->fetchRow()) {
|
||
$result[] = $row;
|
||
}
|
||
} else if ($this->cacheQuery == true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
|
||
$result = array();
|
||
$this->cacheQuery = false;
|
||
while ($row = $this->fetchRow()) {
|
||
$result[] = $row;
|
||
}
|
||
$this->SetCacheFile($this->query . 'FetchAllRow');
|
||
$this->CacheWrite($result);
|
||
} else {
|
||
$result = $this->CacheRead();
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/* Zwraca liczbe wierszy */
|
||
|
||
public function NumRows() {
|
||
if (!$this->result) {
|
||
throw new MysqlException("Query failed");
|
||
}
|
||
$this->SetCacheFile($this->query . 'NumRows');
|
||
|
||
if ($this->cacheQuery == false) {
|
||
if (!$this->result)
|
||
$this->Execute();
|
||
|
||
$result = mysqli_num_rows($this->result);
|
||
}
|
||
|
||
else if ($this->cacheQuery == true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
|
||
if (!$this->result)
|
||
$this->Execute();
|
||
|
||
$result = mysqli_num_rows($this->result);
|
||
|
||
$this->CacheWrite($result);
|
||
} else {
|
||
$result = $this->CacheRead();
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/* Zwraca wiersz w postaci tablicy */
|
||
|
||
public function FetchArray() {
|
||
if (!$this->result) {
|
||
throw new MysqlException("Query failed");
|
||
}
|
||
$this->SetCacheFile($this->query . 'FetchArray');
|
||
|
||
|
||
|
||
if ($this->cacheQuery == false) {
|
||
if (!$this->result)
|
||
$this->Execute();
|
||
|
||
$result = mysqli_fetch_array($this->result);
|
||
}
|
||
|
||
else if ($this->cacheQuery == true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
|
||
|
||
if (!$this->result)
|
||
$this->Execute();
|
||
|
||
$result = mysqli_fetch_array($this->result);
|
||
|
||
$this->CacheWrite($result);
|
||
} else {
|
||
$result = $this->CacheRead();
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Zwraca id ostatnio zmienionego rekordu
|
||
*
|
||
* @return integer
|
||
*/
|
||
public function GetInsertionId() {
|
||
if (!$this->result) {
|
||
throw new MysqlException("Query failed");
|
||
}
|
||
return mysqli_insert_id($this->dbh);
|
||
}
|
||
|
||
/**
|
||
* Zwraca liczb<7A> zmienionych rekord<72>w w ostatnim zapytaniu modyfikuj<75>cym dane.
|
||
*
|
||
* @return integer
|
||
*/
|
||
public function GetAffectedRows() {
|
||
if (!$this->result) {
|
||
throw new MysqlException("Query failed");
|
||
}
|
||
return mysqli_affected_rows($this->dbh);
|
||
}
|
||
|
||
/**
|
||
* Sprawdza czy zaoytanie jest cacheowane
|
||
*
|
||
* @return boolean
|
||
*/
|
||
public function CacheCheck() {
|
||
|
||
if (($this->cacheEnable == true && (is_file($this->cachePath . $this->cacheFile) && filemtime($this->cachePath . $this->cacheFile) > (time() - $this->cacheTime)))) {
|
||
|
||
return true;
|
||
} else {
|
||
if (is_file($this->cachePath . $this->cacheFile)) {
|
||
touch($this->cachePath . $this->cacheFile);
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Zapisuje cache do pliku
|
||
*
|
||
* @param obj $result
|
||
*/
|
||
public function CacheWrite($result) {
|
||
if ($this->cacheEnable != false) {
|
||
$records = serialize($result);
|
||
$fp = fopen($this->cachePath . $this->cacheFile, "w");
|
||
fputs($fp, $records);
|
||
fclose($fp);
|
||
$this->cacheQuery = false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Odczytuje cache z pliku
|
||
*
|
||
* @return obj
|
||
*/
|
||
public function CacheRead() {
|
||
if (is_file($this->cachePath . $this->cacheFile)) {
|
||
$records = unserialize(file_get_contents($this->cachePath . $this->cacheFile));
|
||
$this->cacheQuery = false;
|
||
return $records;
|
||
} else {
|
||
throw new MysqlException('File does not exist: ' . $this->cachePath . $this->cacheFile);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Uruchamia cacheowanie
|
||
*
|
||
* @param integer $time
|
||
*/
|
||
public function CacheStart($time = null) {
|
||
if ($time != null && $this->cacheEnable != false) {
|
||
$this->cacheTime = $time;
|
||
}
|
||
if ($this->cacheEnable != false)
|
||
$this->cacheQuery = true;
|
||
else
|
||
$this->cacheQuery = false;
|
||
|
||
return $this;
|
||
}
|
||
|
||
/**
|
||
* Ustanawia nazw<7A> pliku cache
|
||
*
|
||
* @param unknown_type $fileName
|
||
*/
|
||
public function SetCacheFile($fileName) {
|
||
$this->cacheFile = md5($fileName);
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Klasa obslugi wynikow zapytan
|
||
*
|
||
*/
|
||
class DBResult {
|
||
|
||
protected $stmt;
|
||
protected $result = array();
|
||
private $rowIndex = 0;
|
||
private $currIndex = 0;
|
||
private $done = false;
|
||
|
||
/**
|
||
* Konstruktor
|
||
*
|
||
* @param DBStatement $stmt
|
||
*/
|
||
public function __construct(DBStatement $stmt) {
|
||
$this->stmt = $stmt;
|
||
}
|
||
|
||
/* Zwraca pierwszy rekord */
|
||
|
||
public function First() {
|
||
if (!$this->result) {
|
||
$this->result[$this->rowIndex++] = $this->stmt->FetchAssoc();
|
||
}
|
||
$this->currIndex = 0;
|
||
return $this;
|
||
}
|
||
|
||
/* Zwraca ostatni rekord */
|
||
|
||
public function Last() {
|
||
if (!$this->done) {
|
||
array_push($this->result, $this->stmt->FetchAllAssoc());
|
||
}
|
||
$this->done = true;
|
||
$this->currIndex = $this->rowIndex = count($this->result) - 1;
|
||
return $this;
|
||
}
|
||
|
||
/* Zwieksza index i zwraca kolejny rekord */
|
||
|
||
public function Next() {
|
||
if ($this->done) {
|
||
return false;
|
||
}
|
||
$offset = $this->currIndex + 1;
|
||
if (!$this->result[$offset]) {
|
||
$row = $this->stmt->FetchAssoc();
|
||
if (!$row) {
|
||
$this->done = true;
|
||
return false;
|
||
}
|
||
$this->result[$offset] = $row;
|
||
++$this->rowIndex;
|
||
++$this->currIndex;
|
||
return $this;
|
||
} else {
|
||
++$this->currIndex;
|
||
return $this;
|
||
}
|
||
}
|
||
|
||
/* Zmniejsza index i zwraca poprzedni wiersz */
|
||
|
||
public function Prev() {
|
||
if ($this->currIndex == 0) {
|
||
return false;
|
||
}
|
||
--$this->currIndex;
|
||
return $this;
|
||
}
|
||
|
||
/**
|
||
* Getter dla pobieranych danych
|
||
*
|
||
* @param string $value
|
||
* @return string
|
||
*/
|
||
public function __get($value) {
|
||
if (array_key_exists($value, $this->result[$this->currIndex])) {
|
||
return $this->result[$this->currIndex][$value];
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Klasa oslonowa naszej bazy danych
|
||
*
|
||
*/
|
||
class DBProd extends DBMysql {
|
||
|
||
protected $user;
|
||
protected $pass;
|
||
protected $dbHost;
|
||
protected $dbName;
|
||
|
||
/**
|
||
* Pusty konstruktor
|
||
*
|
||
*/
|
||
public function __construct() {
|
||
|
||
//$db = Config::Get('db');
|
||
//Utils::ArrayDisplay($db, __FILE__.' - '.__LINE__);
|
||
$this->dbHost = prodHost;
|
||
$this->dbName = prodDb;
|
||
$this->user = prodUser;
|
||
$this->pass = prodPass;
|
||
}
|
||
|
||
public function GetDbh() {
|
||
if (empty($this->dbh)) {
|
||
//$this->Connect(__METHOD__);
|
||
}
|
||
return $this->dbh;
|
||
}
|
||
|
||
}
|
||
|
||
?>
|