gpt4 book ai didi

php - 继承自 Db 类 - 两个数据库连接 | PHP

转载 作者:搜寻专家 更新时间:2023-10-30 23:37:24 24 4
gpt4 key购买 nike

在我的应用程序中,我只使用了一个数据库,并创建了类来提供一些常用方法。现在我需要实现额外的数据库。

因此,我不想创建单独的 Db 类来执行相同的操作,而是想使用与数据库相关的参数调用该 Db 类。

问题是,当我尝试使用我向应用程序提供方法的类扩展 Db 类时,未建立数据库连接 - 它为空。

Main 和 User 都使用不同的数据库。

Main 类扩展了 Db;用户类扩展 Db;

为什么这样的东西不起作用?

class Db {

protected $link;
private $host;
private $user;
private $pass;
private $dbName;

public function __construct($host, $user, $pass, $db) {
$this->host = $host;
$this->user = $user;
$this->pass = $pass;
$this->dbName = $db;
$this->connect();
}

public function connect() {

try
{

$this->link = new PDO("mysql:host=" . $this->host .
";dbname=" . $this->dbName . ";charset=utf8mb4", $this->user, $this->pass );
$this->link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

} catch (PDOException $exc)
{
$this->setMessage($exc->getMessage());
}
}
}
$db = new Db(HOST, USER,PASS,DB)

class Main extends DB {

public function __construct() {

}
/** App methods bellow*/
}

$db2 = new Db(HOST2,USER2,PASS2,DB2);
class User extends DB {

public function __construct() {

}
/** App methods bellow*/
}

实现两个不同数据库连接的最简单解决方案是什么?

谢谢!

编辑:

按照建议更新我的代码后,我在访问数据库的连接属性时遇到问题,因此我无法在 Main 和 User 类中进行查询。

真正让我感到困惑的是,为什么该属性对主类不可见?

主要类方法严重依赖于数据库链接,我不确定如何解决这个问题..

更新代码:

class Main {

protected $db;

public function __construct($db) {
$this->db = $db;
}

public function showFreeSlotsPerPlan() {

try
{
$SQL = "some query";

$stmt = $this->db->prepare($SQL);
/** Prepared statements bellow **/
}
}

class Db {

protected $link;
private $host;
private $user;
private $pass;
private $dbName;

public function __construct($host, $user, $pass, $db) {
$this->host = $host;
$this->user = $user;
$this->pass = $pass;
$this->dbName = $db;
$this->connect();
}
}

并按照建议调用它:

$db = new Db(HOST, USER, PASS, DB);
$main = new Main($db);

如果我尝试调用方法 f.e. showFreeSlotsPerPlan()

Fatal error: Call to undefined method Db::prepare() in /var/www/html/Master/class/Main.class.php 

然后当我调试 Main 实例时,我得到以下信息:

Main Object
(
[db:protected] => Db Object
(
[link:protected] => PDO Object
(
)

[host:Db:private] => localhost
[user:Db:private] => root
[pass:Db:private] => password
[dbName:Db:private] => dbname
)

)

编辑2:解决方法是将 prepare 方法添加到 DB.php,我能够成功执行查询。

我仍然不确定这是不是最好的方法。我承认我的设计一点也不好:(

public function prepare($sqlQuery) {
return $this->link->prepare($sqlQuery);
}

最佳答案

@u_mulder 正确描述了您面临的技术问题。子构造函数不会自动调用父 Db 构造函数。您可以尝试通过显式调用父构造函数来解决此问题:

class Main extends DB 
{

public function __construct()
{
parent::__construct();
}
// ...
}

问题是您的父级 (DB) 需要为其构造函数提供参数,因此您还必须将这些参数传递给您的子级:

class Main extends DB 
{

public function __construct($host, $user, $pass, $db)
{
parent::__construct($host, $user, $pass, $db);
}
// ...
}

但这没有意义。你最大的问题是设计。相反,你应该 favor composition of objects over inheritance ,尤其是在这种情况下。尝试像这样重构你的类:

class Main 
{
protected $db;

public function __construct($db)
{
$this->db = $db;
}
// ...
}

$mainDb = new Db(HOST, USER,PASS,DB)
$main = new Main($mainDb);

并为您的 User 类做同样的事情。当您这样做时,您的 protected $link 属性将不再在您的 Main 类中可见。这没关系,因为,实际上,您的 MainUser不应该具有该属性的可见性,因为有一个 Db 类,无论如何?您可以通过向 Db 类添加一些公共(public)方法(例如 public function query($sql, $parameters))来解决这个问题,然后从您的 中调用这些方法MainUser 类。

一旦你开始工作,我建议你查看 Active Record Pattern ,或者考虑完全放弃您的方法,转而采用众多 open source ORMs 中的一种方法已经可用。

关于php - 继承自 Db 类 - 两个数据库连接 | PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40140510/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com