ugrás a tartalomhoz

Adatbázis és hibakezelés felsőfokon

TIV · 2009. Júl. 12. (V), 14.21
Sziasztok!

Kaptam egy jó kis projectet, amit a közeljövőben kell majd elkezdeni. Szakmailag kihívásnak tekintem, habár jelenlegi tudásommal is simán meg tudnám csinálni, csak nem mindegy hogyan(!), így úgy döntöttem, hogy rátanulok és megpróbálom a lehető legprofibbra megírni. Viszonylag kevés tapasztalatom van OOPban, ezért lenne pár kérdésem...

1. Szeretném - ha úgy döntene az ügyfél, hogy átpakolja a lapot egy másik szerverre - akkor ne legyen belőle túl sok utómunka. Alapvetően MySQL lenne a DB. mysqli kiterjesztéssel gondoltam kezelni és arra gondoltam, hogy létrehozok egy interface-t, ami kiköti miket kell megvalósítani egy pl. DB_MySQL.php osztályban. Egy ilyen példát láttam neten... (ez most nem mysqli, mert csak példa)

public function query($query) { 
   return mysql_query($query, $this->link); 
}
Azt értem, hogy MSSQL-re váltásnál csak egy DB_MSSQL.php-ben csak mssql_query -re kellene átírnom a függvényt, de mi van akkor ha "logikában lévő" lekérdezés nem fut le az új adatbázison? Elképzelhető, hogy annyira különbözni fognak SQLben, hogy az új adatbázis nem érti meg a lekérdezést? Elég gáz lenne, hisz végig kellene nézni az összes oldalt. Elképzelhető h ilyen probléma lesz? Mit lehet ez ellen tenni? A lekérdezéseket is osztályba kellene foglalni?

2. Hibakezelés. Az lenne a cél, hogy hiba esetén kiírjunk valami egyszerű hibaüzenetet és a bővebb információt lementsünk, mondjuk adatbázisba, de nem is ezzel van a gond. Nem teljesen értem a kivétel kezelést. Értem, hogy kivételt kell dobnom ha valami nem oké, de a try catch blokkokat hova kellene tennem? Egy osztályon belül sok metódus van. Mindegyiken belül legyen try catch? Vagy az egész osztályt kellene try-ba tennem? Szóval nem teljesen értem, hogy ha több osztályt használok, akkor hogy lehet ezt a hibakezelést központosítani. A PHP felsőfokon című könyv is csak egy metóduson belül mutatja meg a hibakezelést, de azt h több osztály esetében ez h megy azt nem sajna :(

ui: Angolul tudok, ha valaki linkelni szeretne valami jó kis leírást, amit még nem találtam meg :P :)

Köszönöm mindenkinek a segítséget előre is!
 
1

AdoDB

TIV · 2009. Júl. 12. (V), 14.28
Azt elfelejtettem mondani, hogy ismerem az AdoDB projectet, de jelenleg nem sok esélyt látok arra, hogy sűrűn cserélgetnék majd az adatbázist, ezért nem akartam leterhelni egy ekkora 'rendszerrel' a lapot, viszont mégiscsak szeretném felkészíteni rá a lapot, amennyire lehet. Köszönöm!

ui: lehet valami php keretrendszerrel kellene megismerkednem?
2

Zend Framework, DB minták

erenon · 2009. Júl. 12. (V), 16.17
Ha bele akarsz mélyedni, vess egy pillantást a Zend Frameworkre. Egy nagyon jó DB rétege van, amivel elsimíthatóak a különböző backendek közötti különbségek, persze a megfelelő overheadért cserébe.
Ha nem akarsz ennyi erőforrást rááldozni, - meg egyébként is - vess egy pillantást az adatbázismintákra (Active record, stb.), és zárd be az adatbáziskommunikációt egy modell rétegbe. Így később egyszerű(bb)en át tudod alakítani.

Példa:
//model rétegben:
function getProducts(){
    /* SQL varázslat */
}

//controller rétegben:
$products = $model->getProducts();
Az általad említett queryburkolás kezdetnek jó ötlet lehet, de nem biztos, hogy hosszútávon jó megoldás.
3

PDO

solkprog · 2009. Júl. 12. (V), 16.20
Én PDO-t használok...

üdv,
Balázs
4

try catch

szabo.b.gabor · 2009. Júl. 13. (H), 06.16
Első lépésként csinálj annyit, hogy ahol vmi hiba történik, dobsz egy Exception-t (vagy egy abból származtatott exception-t, vagy ErrorException-t).

pl.

class DB{
	//...
	//...
	function query($query){
		if(!$this->result=$this->db->query($query)){
			if(stripos($this->db->error,'Duplicate entry')!==false){
				throw new DbException('Duplicate entry',DBEX_DUPLICATEENTRY);
			}else{
				throw new DbException("Error in query!\n".$this->db->error."\n".$query."\n",DBEX_QUERY_FAILURE);
			}
		}
		return $this->result;
	}
	//...
	//...
}
a kivételek elkapásával pedig foglalkozz ott, ahol épp szükségesnek látod. pont ez az egyik jó tulajdonságuk. ha nem kapod el őket, akkor a program futása megáll, de az nincs meghatározva, hogy hol kell lekezeld őket. tehát kb annyit jelent, 'ezzel majd csinálni kell valamit..'

előző példára egy használat példa :)

$DB=new DB();

$insertQuery='INSERT INTO valami...';
try{
	$DB->query($insertQuery);
}catch(DbException $e){
	if($e->isDupblicateEntry()){
		$updateQuery='UPDATE valami';
		$DB->query($updateQuery);
	}else{
		throw $e;
	}
}
itt megpróbálunk beszúrni vmit, ha nem sikerül és azért mert Duplicate entry van az adott kulcsra, akkor update-eljük az adott rekordot. ha más miatt volt a DbException pl hibás query miatt, akkor újradobjuk, mert az adott helyen nem szeretnénk foglalkozni vele.
5

Zend_Db_Select kell neked

error · 2009. Júl. 13. (H), 08.49
Sajna jelen idő szerint elég nagy a szakadék az adatbázis-kezelők között SQL szinten. De ha mindenképp szükség van az átjárhatóságra, szerintem a Zend_Db_Select a legjobb megoldás. Tulajdonképp OOP-módon tudod összeállítani a select-et.

$select = new Zend_Db_Select();
$select->from('my_table')
  ->order('title')
  ->limit(10);
echo $select;
Persze a bonyolult lekérdezéseket itt is érdemesebb view-ba tenni.
6

Tiszta sör, mármint sor

TIV · 2009. Júl. 14. (K), 12.19
erenon
Rendben, tehát az adatbázisokkal való kompatibilitásra akarok törekedni mindenek felett, akkor Zend Framework...

erenon, error
Ez a controller, modell, view nem teljesen világos. Ahány osztály, annyi controller és modell fájl kell. A modellben van az összes adatbázis kezelés. A controll meg gondolkodik (logika) és használja a modellen keresztül az adatbázist. Hány view osztály kell? Egy? A controll meghívja a view metódusait és beállít értékeket, amit aztán a view csak kiírat?

szabo.b.gabor
és te melyiket ajánlod? mert akkor végülis 1 try ba is bele lehetne tenni mindent, nem? és ha jól emlékszem, akkor hibakódot is be lehet állítani, ami alapján aztán catchen belül lekezelhetjük különböző hibákat. vagy származtatok annyi féle exceptiont amennyi kell.

ha dobok egy exceptiont, akkor a kód fordítása ott annál a pontnál azonnal megáll, jól gondolom? ha előtte módosítottam egy változót, akkor annak az értéke nem fog visszaállni ugye?

Köszönöm a segítséget!
7

Nézd a profikat

erenon · 2009. Júl. 14. (K), 13.27
Nem tudok most sajnos hosszas fejtegetésbe bocsájtkozni, de próbálok adni egy aranytanácsot:

-Ne találd fel a kereket újra. De még csak meg sem próbáld.

Ha ráérsz, ásd bele magad valamelyik PHP frameworkbe (Zend, Symfony, CakePHP), vagy akár a Drupalba, és elemezd, hogy mit miért csináltak. A Zend MVC kiépítése szerintem elég logikus és lényegretörő, de bármely más nagy kódjából rengeteget lehet tanulni.
Így sokkal gyorsabban megérted majd, hogy mi a model, mi a view és a controller; kár sokat gondolkozni rajta ,)