<?php
class db
{
/***
třída db je databázové rozhraní, momentálně umí jen mysql
Použití:
- můžeme nastavit připojení k databázi pomocí define();, neuděláme-li
to bude použito defultní nastavení z třídy. Je možno toto využít tak,
že nastavení uložíme do samostatného souboru a necháme ho jen na serveru.
potom kontrolujeme jestli soubor existuje a pokud ano je includován.
<?php
//Příklad souboru s konfigurací:
define("SQL_HOST",'adresa.serveru');
define("SQL_USERNAME", 'jmeno.uzivatele');
define("SQL_PASSWORD", 'heslo');
define("SQL_DBNAME", 'nazev_databaze');
?>
příklad ověření jeho existence:
<?php
$cesta = 'db_config.inc.php';
if(file_exists($cesta))
{
include($cesta);
}
?>
- nejprve musíme třídu iniciovat:
$db = &new db();
- můžeme nastavit kódování, znakovou sadu pro spojení s databázi.
Jde to ovšem jen pri inicializaci třídy;
$db = new db('latin2');
- pro ošetření proměnných v dotazech je možno použít metodu Osetri();
pro ošetření je primárně použita funkce 'mysql_real_escape_string()',
pokud není dostupná, je použita funkce mysql_escape_string, pokud
ani ta není dostupná, je použito funkce addslashes();
$db->Osetri('text nebo proměnná kterou chceme ošetřit');
- a samotné vykonání databázového dotazu:
$v = $db->dotaz($dotaz);
nebo:
$v = $db->q($dotaz);
q(); je jen aliasem dotaz();
- Návratové hodnoty podle typu dotazu:
SELECT:
- array() => $v[$poradi_vraceneho_radku][$sloupec]
- true => dotaz je v pořádku ale nic nevrátil
- text => hláška o chybě v db dotaze
INSERT:
- int => číslo je id vloženého záznamu
- 'd' => jedná se o vložení duplicitní hodnoty do sloupce s unique klíčem
- text => hláška o chybě v db dotaze
UPDATE:
- true => dotaz byl vykonán
- 'd' => jedná se o vložení duplicitní hodnoty do sloupce s unique klíčem
- text => hláška o chybě v db dotaze
DELETE:
- true => dotaz byl vykonán
- text => hláška o chybě v db dotaze
***/
var $emailAdmina = "krteczek@jaknato.com";
function __construct($kodovani = 'utf8')
{
//nejprve nastavíme připojení k db podle toho jestli jsou nastavené definice
$this->sqlHost = (defined("SQL_HOST") ? SQL_HOST : '127.0.0.1');
$this->sqlUser = (defined("SQL_USERNAME") ? SQL_USERNAME :'root');
$this->sqlPass = (defined("SQL_PASSWORD") ? SQL_PASSWORD :'');
$this->sqlDb = (defined("SQL_DBNAME") ? SQL_DBNAME :'reality1');
$this->kodovani = $this->Kodovani($kodovani);
$this->pripoj = $this->Pripoj();
}
function q($dotaz)
{
//alias pro dotaz($dotaz);
return $this->dotaz($dotaz);
}
function dotaz($dotaz)
{
/***
Metoda podle prvních 6 znaků vybere funkci, kterou má být zpracován
dotaz, a vrátí jeho návratovou hodnotu
***/
//vytáhneme prvních 6 znaků z dotazu a převedeme na velá písmena
$typ = strtoupper(substr($dotaz, 0, 6));
switch($typ)
{
case 'INSERT': $vysledek = $this->Insert($dotaz); return $vysledek; break;
case 'UPDATE': $vysledek = $this->Update($dotaz); return $vysledek; break;
case 'DELETE': $vysledek = $this->Delete($dotaz); return $vysledek; break;
case 'SELECT': $vysledek = $this->Select($dotaz); return $vysledek; break;
default: return $this->Error($this->dotaz);
}
}
function in($zacatek, $array, $konec = '')
{
/*
tato metoda má za úkol ulehčit sestavení INSERT a UPDATE dotazů
vstup jsou 3 parametry:
$zacatek => "INSERT INTO `tabulka`" "UPDATE `tabulka` SET"
$array => jsou to vkládáná data, kdy klíč je název sloupce a hodnota je hodnota kterou vkládáme
Příklad:
$in = array(
'nazev_clanku' => 'Název článku',
'obsah' => 'nějaký obsah článku',
);
$konec => to jsou podminky za jakých má dojít k update dotazu, čili klauzule WHERE atd
*/
$typ = strtoupper(substr($zacatek, 0, 6));
switch($typ)
{
case 'INSERT': $vysledek = $this->Insert_($zacatek, $array, $konec); return $vysledek; break;
case 'UPDATE': $vysledek = $this->Update_($zacatek, $array, $konec); return $vysledek; break;
default: return $this->Error($this->dotaz);
}
}
function Insert_($dotaz, $array, $konec = '')
{
$a = 0;
$sloupce = '';
$hodnoty = '';
foreach($array as $key =>$foo)
{
if($a === 1)
{
$sloupce .= ', ';
$hodnoty .= ', ';
}
$sloupce .= '`' . $key . '`';
$hodnoty .= $this->O($foo);
$a = 1;
}
$d = $dotaz . "(" . $sloupce . ') VALUES (' . $hodnoty . ') ' . $konec;
return $this->q($d);
}
function Update_($dotaz, $array, $konec = '')
{
$a = 0;
$d = '';
foreach($array as $key =>$foo)
{
if($a === 1)
{
$d .= ', ';
}
$d .= '`' . $key . '` = ' . $this->O($foo) . ' ';
$a = 1;
}
$d = $dotaz . ' ' . $d . ' ' . $konec;
return $this->q($d);
}
function Kodovani($kodovani = 'utf8')
{
//zjistí jaké kodování je třeba použít
$this->kodovani = $kodovani;
return $this->kodovani;
}
function Pripoj()
{
/***
Připojení k databázi.
je použito perzistentní připojení kvůli rychlejšímu
zpracování db dotazů u jednoho běžícího scriptu.
(nemusí se čekat na další připojení k db)
3 kroky:
1. pripojeni k databazovemu stroji
2. pripojeni k databazi
3. nastaveni kodovestranky pro pripojeni k databazi
***/
if((!$this->pripoj = @mysql_pconnect($this->sqlHost, $this->sqlUser , $this->sqlPass)))
{
$text = 'Je mi líto, databáze je nedostupná... Nastala chyba připojení k DB: <b>připojovací údaje k databázi jsou špatné</b>';
triger_error($text, E_USER_ERROR);
}
if(!@mysql_select_db($this->sqlDb))
{
$text = 'Je mi líto, databáze je nedostupná... Chyba: neznámá DB';
triger_error($text, E_USER_ERROR);
}
mysql_query("SET NAMES '" . $this->kodovani . "'");
return $this->pripoj;
}
function Insert($dotaz)
{
/**
* funkce pro ukládání dat do databáze
* pokud se dotaz úspěšně vykoná, vrátí id vloženého záznamu
* pokud selže, kontroluje se zda jde o duplicitu, pokud ano vrátí 'd'
***/
if(mysql_query($dotaz, $this->pripoj))
{
return mysql_insert_id();
}
if(mysql_errno() == 1062)
{
return 'd';
}
return $this->Error($dotaz);
}
function Update($dotaz)
{
/**
* funkce pro úpravu/změnu dat v databázi
* pokud se dotaz úspěšně vykoná, vrátí true
* pokud selže, kontroluje se zda jde o duplicitu, pokud ano vrátí 'd'
***/
if(mysql_query($dotaz, $this->pripoj))
{
return true; //($mod == 0 ? true : mysql_affected_rows());
}
if(mysql_errno() == 1062)
{
return 'd';
}
return $this->Error($dotaz);
}
function Delete($dotaz)
{
/***
Funkce pro vykonání smazání požadovaného záznamu z tabulky
***/
if(mysql_query($dotaz, $this->pripoj))
{
return true;
}
return $this->Error($dotaz);
}
function Select($dotaz)
{
/***
* funkce pro vytáhnutí dat z databáze
* vykoná dotaz, a zapíše do pole vrácené záznamy, ty vrátí skriptu
* v podobě pole $nazev[pocet_zaznamu_od_nuly][nazvy_jednotlivych_polozek]
* Pokud není nalezen záznam, vrátí true
***/
if($v = mysql_query( $dotaz, $this->pripoj))
{
$p = mysql_num_rows($v);
if($p > 0)
{
$out = array();
for($i = 1; $i <= $p; $i++)
{
$r = mysql_fetch_assoc($v);
foreach($r as $key => $foo)
{
$r[$key] = $foo;
}
$out[] = $r;
}
mysql_free_result($v);
return $out;
}
return true;
}
return $this->Error($dotaz);
}
function O($polozka, $numero = false)
{
//alias k Osetri
return $this->Osetri($polozka, $numero);
}
function Osetri($polozka, $numero = false)
{
/***
metoda slouží k ošetření vstupních řetězců použitých v db dotazech
je ji možné zavolat až po inicializaci
metoda na ošetření používá funkci mysql_real_escape_string,
pokud není dostupná, použije mysql_escape_string, pokud
ani tato není dostupná, použije addslashes.
string umístí do apostrofu
***/
//ověříme jestli jsme již připojeni k db, pokud ne zavoláme metodu, která připojení zařídí
if(empty($this->pripoj))
{
$this->pripoj = $this->Pripoj();
}
/*
Protože se ošetřují jen textové řetězce, zjistíme, jestli je obsah text, nebo nějaké číslo
pokud bude truhý parametr 'true' a jedná se o číslo, ale bude také ošetřeno jako řetězec,
vhodné pro telefonní čísla například
16.7.2007: doplněna kontrola na null,true/false a now()
*/
if((!is_numeric($polozka)) ||($numero === false))
{
if(($polozka === NULL) || (strtolower($polozka) == 'null'))
{
$polozka = 'NULL';
}
elseif(strtolower(trim($polozka)) == 'now()')
{
$polozka = 'now()';
}
elseif($polozka === true)
{
$polozka = true;
}
elseif($polozka === false)
{
$polozka = false;
}
else
{
$polozka = "'" . (function_exists('mysql_real_escape_string') ? mysql_real_escape_string($polozka, $this->pripoj) : (function_exists('mysql_escape_string') ? mysql_escape_string($polozka) : addslashes($polozka)) ) . "'";
}
}
return $polozka;
}
function Error($dotaz)
{
$datum = date("Y_m_d");
$file = dirname(__FILE__) . '/log/' . $datum . '_log.db.txt';
$nr = "\n\n";
$od = "/*********************************************************************/";
$script = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'] . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '' );
$log = $nr . $od . $nr . date("Y m.d H.i.s") . ": " . $nr . $dotaz . $nr . mysql_errno() . $nr . mysql_error();
if(((file_exists($file)) && (filesize($file) < (1073741824 * 4))) || (!file_exists($file)))
{
file_put_contents($file, $log, FILE_APPEND);
}
/*
toto zatim nejede
$dotaz = "INSERT INTO `dbError` (`dotaz`, `cas`, `script`, `chyba`) VALUES (" . $this->O($dotaz) . ", new, " . $this->O($script) . ", " . $this->O(mysql_error()) . ",)";
$v = $this->q($dotaz);
//ulozime to do souboru
$email = "Došlo k chybě při vykonávání db dotazu: " . $nr . $dotaz . $nr . " na stránce: http://" . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'] . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '' ) . " Databáze vrátila chybu: " . mysql_error() . "\n\r\n\r";
//$e = db_posli_mail($email);
vratime text a ten se použije v error_triger
*/
return 'Litujeme, došlok chybě při práci s databázi. kontaktujte prosím správce ' . $this->emailAdmina . '';
}
}
?>