Php/Mysql: Database class and dependency injection -
i'm trying adopt dependency injection pattern mid-scale project have been working on. of classes interact database on level , instead of instantiating pdo object inside each class, instantiate single pdo object on controller level , inject object classes require database connection. way, classes using same connection , whole process making unit testing pretty easy.
however, things little bit complex when try use transaction these classes. our database heavily de-normalized , each action requires multiple inserts/updates different classes. give basic example, let's have classes below:
class student{ public function addcourse($pdo,$course){ //$pdo->execute(); } } class course{ public function incrementstudentcount($pdo){ //$pdo->execute(); } }
as see, both addcourse , incrementstudentcount methods must work in single transaction mode.however,student , course classes not aware of whether transaction started or not in $pdo object. don't know if rollback required in case problem occurs.
i thought of creating pdo wrapper class , using class database interactions. way, can keep transaction state inside class. basically, looks this:
class pdowrapper { private $transactionstarted=false; private $pdo; public function __construct($pdo){ $this->pdo=$pdo; } public function starttransaction(){ $this->transactionstarted=true; $this->pdo->begintransaction() } public function query($query){ try{ //$this->db->execute($query); } catch(pdoexception e){ if($this->transactionstarted){ $this->db->rollback(); } } } }
well, i'm not sure approach way go. so, suggest?
you're right in classes should not know going on in other class / db. none of matters, student
, user
classes concerned inserting database.
it shouldn't matter if there's transaction or not: should still doing exact same thing they'd doing regardless, inserting rows. i'd recommend have controller takes care of both tasks, so:
$pdo->starttransaction(); //however instantiate course object, here $course = new course; //same student $student = new student; $student->addcourse($pdo, $course); $course->incrementstudentcount($pdo); $pdo->commit();
when commit database, queries go through. can rollback in case of error so:
try { $pdo->starttransaction(); //code } catch(pdoexception $e) { $pdo->rollback(); }