Files
zurawik.pl/core/class/DB.class.php
2026-05-15 20:23:25 +02:00

711 lines
15 KiB
PHP
Raw Permalink Blame History

<?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;
}
}
?>