php - 如何将数据库传递给类?
问题描述
我正在使用此处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
}
索引.php
$frontController = new FrontController($dbh);
$frontController->run();
上面的代码有效,但感觉很笨拙。FrontController 仅用于路由应用程序,永远不会访问数据库本身。因此,它不需要知道该$dbh
对象,除非它会创建其他需要知道$dbh
该类的对象。这也意味着如果 FrontController 创建了另一个不需要$dbh
该类的对象,该对象无论如何都会获得该类,因为 FrontController 正在向每个人$dbh
传递一个副本。$dbh
我的问题是:是否有一种更简洁的方法可以将数据库传递给 FrontController 创建的对象,以便只有需要它的对象才能获得它,并且只有在他们需要它的时候才能获得它?我正在尝试遵循最佳实践/基本原则,但我在本网站或其他地方找不到任何反映这种情况的问题。据我所知,这是正确的做法,但我怀疑不是。
解决方案
您可以将数据库调用包装在这样的类中。
class database {
function connect(){
$dbh = new PDO('mysql:host='.$host.';dbname='.$database, $user, $pass);
return $dbh;
}
}
那么,如果你只需要函数 run中的数据库,你可以这样做
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
}
推荐阅读
- emacs - 在议程列视图中显示继承的属性
- asp.net-mvc - 使用 IIS Windows 身份验证、MVC 和 [Authorize(Roles = "Admin")] 时,这是域管理员吗?
- android - 如何验证用户是否有网络访问权限并在没有网络访问权限时显示弹出警报
- android - 想要使用查询方法添加 where 子句以获取具有特定 id 的行
- c++builder - VCL TListView 和 EditCaption()
- server - 网络解决方案 通过nodemailer配置SMTP邮件
- css - 如何将标题移动到 Bootstrap 4 卡片项目内的文本左侧?
- mongodb - 如何启动 mongod 但忽略现有数据库文件中的无效索引?
- python - Django Python json 加载显示 /x97
- java - 在 HashMap 中打印排序的列表值