OOP-s adatbázis kezelés minta
Sziasztok!
Próbálok ismerkedni az OOP rejtelmeivel, még csak kezdő szinten, és szeretném kikérni a véleményetek az alábbi kóddal kapcsolatban, mely egy adatbázis kezelő osztály kezdeti verziója lenne, csupán az OOP gyakorlása végett.
De jó úton haladok-e, nem bonyolítom-e túl, mi az amit rosszul csináltam?
Azért kérdem, mert annyi a témába vágó minta kódot találtam, de mindegyik egy kicsit másképp van megalkotva, ezért gondoltam, hogy akkor a saját logikám szerint megalkotnám.
Olyan kódot szerettem volna létrehozni, ami alkalmas PDO, mySQLi vagy egyéb API felhasználására is. Természetesen még nincs kész, de jó-e a szemlélet, szervezés?
config.phpdb.phpindex.phpKöszönöm, ha segítetek!
u.i.: Tudtok esetleg olyan oldalt ajánlani, ahol minta feladatok vannak fent (jóféle) megoldásokkal.
■ Próbálok ismerkedni az OOP rejtelmeivel, még csak kezdő szinten, és szeretném kikérni a véleményetek az alábbi kóddal kapcsolatban, mely egy adatbázis kezelő osztály kezdeti verziója lenne, csupán az OOP gyakorlása végett.
De jó úton haladok-e, nem bonyolítom-e túl, mi az amit rosszul csináltam?
Azért kérdem, mert annyi a témába vágó minta kódot találtam, de mindegyik egy kicsit másképp van megalkotva, ezért gondoltam, hogy akkor a saját logikám szerint megalkotnám.
Olyan kódot szerettem volna létrehozni, ami alkalmas PDO, mySQLi vagy egyéb API felhasználására is. Természetesen még nincs kész, de jó-e a szemlélet, szervezés?
config.php
<?php
DEFINE('DB_HOST', 'localhost');
DEFINE('DB_NAME', 'asasd');
DEFINE('DB_USER', 'sdssdsd');
DEFINE('DB_PASS', 'dfgdfgfgdf');
?>
<?php
require_once('config.php');
interface DBConnection{
public function db_connect();
//public function db_disconnect();
//public function db_is_connected();
}
interface DBQuery{
public function select($query);
//public function select_all($query);
//public function delete($query);
//public function update($query);
}
abstract class DB implements DBConnection{
protected $db_host = DB_HOST;
protected $db_name = DB_NAME;
protected $db_user = DB_USER;
protected $db_pass = DB_PASS;
protected $db_conn = null;
}
final class PDOConnection extends DB implements DBQuery{
private $stmt = null;
function __construct(){
$this->db_connect();
}
function db_connect(){
$this->db_conn = new PDO("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass);
}
function select($query){
$this->stmt = $this->db_conn->prepare($query);
$this->stmt->execute();
return $this->stmt->fetchAll();
}
}
//final class SQLiConnection extends DB implements DBQuery{}
?>
<?php
ini_set("display_errors", true);
error_reporting(E_ALL);
require_once('db.php');
$pdo = new PDOConnection;
$result = $pdo->select("SELECT name FROM user");
?>
u.i.: Tudtok esetleg olyan oldalt ajánlani, ahol minta feladatok vannak fent (jóféle) megoldásokkal.
Hibak
Ezen felul erdemes lenne kulonbseget tenni a kulonbozo DB motort tamogato konnektorok kozott, hiszen nem fognak ugyanugy viselkedni.
Ha szeretnel egy peldat latni egy OOP elveket koveto SQL libre, nezd meg ezt a projekt-kezdemenyt. Ugyan nincs kesz, de a lenyeg remelhetoleg ertheto belole.
Altalanos jotanacsok:
- Minden osztalyod legyen kulon fajlban a PSR-4 szabvany szerint. Ennek megfeleloen hasznalj PSR-4 betoltot.
- Ha mar atalltal PHP 7-re, dokumentald a fuggvenyeid visszateresi tipusat. Ha nem, akkor PHPDocban ird le.
- A konfigodat es fuggosegeidet add at konstruktor parameterben, ne implicit modon legyen beleegetve.
Ilyenek tanácsokra gondoltam,
Nagyon köszönöm! Utánanézek, aztán visszajövök!
Google
- SOLID elvek
- Dependency injection
Megnéztem amit linkeltél, de
Viszont az elméleti dolgok nagyon hasznosak, köszönöm!
Kérdések
Miért több API-van szeretnéd használni?
Azon a szinten, ahol most vagy, általában egyféle adatbázishoz szoktak csatlakozni. Ha már többhöz kell, az macera, még akkor is, ha az SQL dialektusait beszélik, mert a kompatibilitás nagyjából az alap SELECT, INSERT és társaikig tart, de már egy JOIN megfogalmazásánál is eltérőek lehetnek a különböző motorok, nem beszélve a típusosságról.
Miért MySQL? Igaz, hogy gyorsabb, mint a PostgreSQL, és kényelmesebb is benne lekérdezéseket írni, mert a típusellenőrzéseket elvégzi a háttérben, de ez egyben hátránya is, mert ha később komolyabban szeretnél SQL-lel foglalkozni, ott ezt nem úszhatod meg, azaz a PostgreSQL jobb belépő, ráadásul az SQL szabványt is pontosabban valósítja meg.
Emellett a MySQL GPL lincesszel fut, ami olyan, mint a rák, ha valamit megfertőz, soha nem fog szabadulni tőle. Ezzel szemben a PostgreSQL-t egy szabad MIT lincesszel adják, így azt teszel vele, amit akarsz. Példa: az általunk fejlesztett szolgáltatás nem csak központi szerveren fut, hanem az ügyfeleknek lehetősége van tőlünk egy minigépet venni, így az adatok ott vannak náluk. Ezt MySQL-lel nem tudnánk megcsinálni, azaz igen, de ügyfelenként félmilliós díjat kéne fizetni. Áttértünk PostgreSQL-re, és ez meg is oldódott.
Valóban szükség van arra, hogy a PHP-d meghívásakor több adatbázishoz is csatlakozz? Ha nem, akkor miért OOP módon teszed? Írhatsz egy egyszerű
db_lekerdezes()
,db_beszur()
,db_torol()
stb. függvényt, amit bárhonnan könnyen elérhetsz a kódból.Mi például két-három adatbáziskapcsolatot használunk, a fenti függvényeknek pedig paraméterként adjuk át, hogy melyiken végezze el a műveletet.
De ha már PDO, akkor miért foglalkozol az eggyel egyszerűbb MySQLi-vel? A PDO egy absztrakciós réteg a natív adatbázisfüggvények felett. Viszont, mint fentebb írtam, tapasztalataim szerint elég nagy eltérések vannak már a MySQL és a PostgreSQL között is, nagyon nehéz az alap Móricka szint fölött olyan lekérdezéseket írni, amelyek mindkettőben egyformák.
Vagy fordítva: ha viszont nincs szükséged a PDO funkcionalitására, miért nem használod közvetlenül a MySQLi függvényeket? A PDO-t sokan azért használják, mert lehetőség van benne prepared statementek írására. Ezt viszont natív MySQLi függvényekkel is megteheted, így némileg gyorsabb lesz a programod.
A PHP PostgreSQL függvényei között vannak, amelyek – hasonlóan a prepared statementekhez – a kapott paramétereket escape-elik, azaz neked nem kell ezzel foglalkoznod (
pg_insert
,pg_update
,pg_delete
,pg_query_params
).A prepared statementek drágák, mert kétszer kell őket elküldeni az adatbázisszervernek (egyszer előkészíti őket, azaz elvégzi az escape-elést, egyszer pedig lefuttatja a lekérdezést). Persze van előnyük is, ha ugyanazt a lekérdezést többször is meghívod, csak más paraméterekkel, akkor végül gyorsabb lesz a program. Csak tapasztalatom szerint nem sok ilyen alkalom van.
---
Ha objektumorientált programozást szeretnél tanulni, a fentiekből látszik, hogy nem feltétlenül az adatbázisok kezelése a legjobb terep erre.
MySQLi
rejtett global scope van a
Pl
Az utolsó mondatodban a
Szóval úgy néz ki, hogy nem a legjobb feladatot találtam erre, viszont nem találtam olyan oldalt, ahol kiírnak egy feladatot, melynek megvalósítása során nem csak 1 osztályra korlátozódik, illetve ki kell valamennyire használni az OOP lehetőségeit. No, meg persze, aztán kapok egy alternatívát a megoldást illetően, hogy összehasonlíthassam a saját kódommal. Mert, ha nincs, akkor review-hatom magam, nem biztos, hogy jól fog elsülni a dolog :).
Ha valaki ismert ilyen forrást, akkor azt szívesen venném. Vagy keressek egy könyvet? No, de melyiket?
Ha valaminek az
Ezt értem :), tök jó,