Как передать базу данных в класс? - PullRequest
0 голосов
/ 06 августа 2020

Я использую шаблон Front Controller, найденный здесь https://www.sitepoint.com/front-controller-pattern-1/. Поэтому все классы в моем приложении создаются в функции run() на моей странице index.php:

$frontController = new FrontController();
$frontController->run();

Я получаю доступ к своей базе данных через PDO с помощью $dbh = new PDO('mysql:host='.$host.';dbname='.$database, $user, $pass);

Моя проблема в том, что я не знаю, как передать базу данных объектам, созданным FrontController.

Я пробовал передать базу данных FrontController, а затем передать ее класс в FrontController. Упрощенный пример показан ниже.

$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();

Приведенный выше код работает, но кажется неуклюжим. FrontController используется только для маршрутизации приложения и никогда не будет обращаться к самой базе данных. Следовательно, ему не нужно знать об объекте $dbh, за исключением того, что он создаст другие объекты, которым необходимо знать о классе $dbh. Это также означает, что если FrontController создает другой объект, которому не нужен класс $dbh, этот объект все равно получит класс $dbh, потому что FrontController раздает копию $dbh всем.

Мой вопрос: : есть ли для меня более чистый способ передать базу данных объектам, созданным FrontController, чтобы только те объекты, которым она нужна, получали ее, и только тогда, когда она им нужна? Я пытаюсь следовать принципам best practice / basi c, но не могу найти на этом сайте или в другом месте вопросов, отражающих эту ситуацию. Насколько я знаю, это правильный способ сделать это, но я подозреваю, что это не так.

1 Ответ

0 голосов
/ 06 августа 2020

вы можете обернуть вызов базы данных внутри такого класса.

class database {
   function connect(){
      $dbh = new PDO('mysql:host='.$host.';dbname='.$database, $user, $pass);
      return $dbh;
   }
}

тогда, если вам нужна только база данных в запуске функции , вы можете сделать это

class FrontController {
//.....
function run(){
    $dbh = (new database)->connect();
  //...
}
}

для класса пользователя вы можете использовать как пользователь, который вы использовали, или вы также можете использовать код ниже.

class User {
    
    public $dbh;

    function __construct(){
        $this->dbh = (new database)->connect();
    }

    function get_username_from_db(){
        $stmt = $this->dbh->prepare(...);
        //etc
}
...