php - How to pass database to class?

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 therun()
function on myindex.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.
Answer
Solution:
you can wrap database call inside a class like this.
class database {
function connect(){
$dbh = new PDO('mysql:host='.$host.';dbname='.$database, $user, $pass);
return $dbh;
}
}
then, if you only need database in function run, you can do this
class FrontController {
//.....
function run(){
$dbh = (new database)->connect();
//...
}
}
for user class you can either user as you have used or you can also use below code.
class User {
public $dbh;
function __construct(){
$this->dbh = (new database)->connect();
}
function get_username_from_db(){
$stmt = $this->dbh->prepare(...);
//etc
}
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: php_network_getaddresses: getaddrinfo failed: temporary failure in name resolution
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.