【发布时间】:2017-01-22 13:06:30
【问题描述】:
我正在尝试更多地了解 PHP 中的 OOP,所以我设置了一个简单的情况。
我有一个 MySQL 数据库,其中包含一个带有钱包的表。然后我做了以下课程:
class WalletConnection {
private $db;
private $user_id;
private $wallets;
public function __construct ($user_id) {
$this->user_id = $user_id;
$this->db = new PDO('mysql:host=localhost;dbname=ws;charset=utf8', 'dbuser', '***');
$this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
public function loadWallets () {
$sql = $this->db->prepare('SELECT id, CurrencyCode, Balance FROM wallets WHERE UserID = :UserID');
$sql->execute([':UserID' => $this->user_id]);
$this->wallets = $sql->fetchAll(PDO::FETCH_ASSOC);
}
public function getWallet ($num) {
// do something like: new Wallet($this->wallets[$num])
}
}
然后我像这样创建钱包连接:
$wallets = new WalletConnection(40); // 40 = UserID of wallet owner
$wallets->loadWallets();
现在我想创建一个子类 Wallet 来处理个人钱包。
class Wallet extends WalletConnection {
private $id, $balance, $currency_code;
public function __construct($data) {
$this->id = $data['id'];
$this->balance = $data['Balance'];
$this->currency_code = $data['CurrencyCode'];
}
public function getBalance() {
}
}
要了解有关 OOP 的更多信息,我想构建这个:
$wallet = $wallets->getWallet(0); // This will now contain the id, CurrencyCode, Balance of the first wallet of the parent's $wallets.
所以我想我需要在 WalletConnection 类中添加一个 getWallet() 函数并从那里调用“new Wallet”。
然后在我想做的客户端代码中:
$wallet->getBalance()
目前我不知道我这样做是否正确,如果我需要知道下一步该做什么以确保例如 getBalance() 函数可以使用父级的 $db 连接.
【问题讨论】:
-
当然,在
getWallet()方法中通过new Wallet实例化一个新钱包确实有意义。然后,您将该钱包返回到外部范围。正好。但是,您想将该对象“缓存”在$wallets对象中,以防它被第二次调用。在这种情况下,您确实不想创建第二个对象,我想。您可以为此在WalletConnection类中定义一个属性。如果它已经为特定索引保存了一个对象,则返回该对象,否则实例化、缓存并返回一个新对象。 -
好的,但是当我从 getBalance() 调用函数以在 Parent 中运行 sqlQuery 时,$this 变成了“孩子的”$this,因此 $this->db 变得不可用。我不想为每个钱包创建新的连接。
-
好吧,您可以通过构造函数将数据库对象“注入”到钱包对象中,或者更优雅地,您可以在钱包中存储对 WalletCollection 的反向引用,这样您就可以使用它钱包对象内的对象数据库连接。
-
我用一个简单的(非数据库)示例尝试了最后一部分。我在 WalletConnection 中添加了:protected function getUserID () { return $this->user_id; } -- 现在,如果我从钱包(子)调用 $this->getUserID(),那么它是空的,因为父级的 getUserID() 中的 $this 现在是子级的 $this() 而不是父级的。
-
哇,对不起,我没注意。您的问题是您实际上从
WalletConnection类派生了Wallet类,这实际上没有意义。WalletConnection实现了一组东西,但钱包实现了其中一个特定的东西。因此它们描述了完全不同的语义含义。那么为什么要从WalletConnection扩展Wallet?