2017-01-22 10 views
0

PHPでOOPについてもっと学びたいので、私は簡単な状況を設定します。PHP:親クラスと子クラス

私はウォレットを備えたテーブルを保持する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(); 

今、私は、個々の財布で動作するように子クラスウォレットを作成したいです。

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()関数を追加し、そこから「新しいウォレット」コールする必要があると思います。

私がやりたいクライアントコードで

そして:

$wallet->getBalance() 

瞬間に私はこの正しい方法をやっている場合、私は知らない、と私は場合、私は何をすべきかを知っておく必要があります次にgetBalance()関数が親の$ db接続を使用できることを確認します。

+0

もちろん、新しいウォレットを 'getWallet()'で 'new Wallet'でインスタンス化していますthodは理にかなっています。そのウォレットを外の範囲に戻します。ちょうど良い。しかし、 '$ wallets'オブジェクトでそのオブジェクトを「キャッシュ」したい場合は、2回目と呼ばれます。あなたはそのような場合に2番目のオブジェクトを作成したくないと思います。そのために、 'WalletConnection'クラスでプロパティを定義することができます。そのオブジェクトがすでに特定のインデックスのオブジェクトを保持している場合はそれを返し、それ以外の場合はインスタンス化し、キャッシュして返します。 – arkascha

+0

しかし、getBalance()の関数を呼び出して親の内部でsqlQueryを実行すると、$ thisは "Child's" $ thisになるので、$ this-> dbは使用できなくなります。私はすべてのウォレットのための新しい接続を作成したくありません。 –

+0

さて、データベースオブジェクトをコンストラクタ経由でウォレットオブジェクトに「注入」するか、ウォレットオブジェクトの内部でそのオブジェクトデータベース接続を使用できるように、ウォレットのウォレットコレクションへの逆参照を格納するか。 – arkascha

答えて

1

OOPの基本について知りたい場合は、OOP開始の詳細を知りたい場合。 http://codebetter.com/raymondlewallen/2005/07/19/4-major-principles-of-object-oriented-programming/

あなたは、あなたのDBとウォレット間の依存関係を作ることによってそれをここに違反している、特に以来、深いカプセル化校長に飛び込む必要があります。

モデルとしてウォレットを作成し、それに関連する機能(getWalletByIdなど)を担当するサービスを作成することをお勧めします。

データベース(通常は配列)から情報を取得し、それをウォレットモデルにマップする方法を知っているマッパーが必要です。

また、ウォレットで作業するのではなく、データベースに接続できるアダプタを使用したいとします。

拡張は必ずしも解決ではないことを覚えておいてください。継承よりも合成を使用する必要があることがあります。

たとえば、サービスにはマッパーが含まれており、マッパーにはアダプターが含まれています。

このような何かしようと、物事をまとめると:

  1. 財布モデルを作成します。ウォレットサービスを作成します。ウォレットを作成する マッパー。 PDOアダプタを作成します。
  2. 使用PDOアダプタは、生SQL財布データ
  3. が適切財布モデルに配列地図やサービスを通じてマッパー
  4. リターンを通じてウォレットモデルをそれを返す取得します。最後に

あなたは、単一のコード行が必要です:

$wallet = $walletService->getWalletById($id); 

をそして、あなたは公共であることによって、またはゲッターでその属性を使用することができるはずです。

$balance = $wallet->balace; 

$balance = $wallat->getBalance(); 
関連する問題