I am using the Front Controller pattern found here https://www.sitepoint.com/front-controller-pattern-1/. Therefore all classes in my application are created in the run()
function on my index.php
page:
$frontController = new FrontController();
$frontController->run();
I am accessing my database via PDO with $dbh = new PDO('mysql:host='.$host.';dbname='.$database, $user, $pass);
My problem is I don't know how to pass the database to the objects created by the FrontController.
I have tried passing the database to the FrontController and then passing it to the class within the FrontController. Simplified example shown below.
$dbh = new PDO('mysql:host='.$host.';dbname='.$database, $user, $pass);
class FrontController {
const DEFAULT_CONTROLLER = "IndexController";
const DEFAULT_ACTION = "index";
protected $controller = self::DEFAULT_CONTROLLER;
protected $action = self::DEFAULT_ACTION;
protected $params = array();
protected $basePath = "";
protected $dbh;
public function __construct($dbh, array $options = array()) {
$this->dbh = $dbh;
if (empty($options)) {
$this->parseUri();
}
else {
//set controller, action and params
}
}
public function run() {
call_user_func_array(array(new $this->controller($this->dbh), $this->action), $this->params);
}
}
class User {
public $dbh;
function __construct($dbh){
$this->dbh = $dbh;
}
function get_username_from_db(){
$stmt = $this->dbh->prepare(...);
//etc
}
index.php
$frontController = new FrontController($dbh);
$frontController->run();
The above code works, but it feels clunky. The FrontController is only used for routing the application and will never access the database itself. It therefore has no business knowing about the $dbh
object, except that it will create other objects that do need to know about the $dbh
class. It also means if the FrontController creates another object that doesn't need the $dbh
class, that object will get the $dbh
class anyway because the FrontController is passing out a copy of $dbh
to everyone.
My question is: is there a cleaner way for me to pass the database to the objects created by the FrontController, so that only the objects that need it get it, and only when they need it? I'm trying to follow best practice/basic principles but I can't find any questions on this site or elsewhere that reflect this situation. For all I know this is the right way of doing it, but I suspect it's not.