2012-11-01 4 views
5

クラスとオブジェクトを利用するPHPで私の最初のアプリケーションを書く。 複数のデータベースがあるため、適切な設定を選択するために文字列を使用するDBクラスがあります。私はログインクラスを使い始めましたが、ユーザークラスと引き換えにそのアイデアを傷つけて、user-> isLoggedInのようにすることができます。ユーザークラスは、ユーザーとログイン情報を格納するMySQLと、2番目のデータベースの資格情報を使用します。OOP PHPの新機能、指導要求、クラス間のデータ共有設計

$mysql = new db('mysql'); 

$user = new user($mysql); 
if(!($user->isLoggedIn() === true)) 
{ 
    goToPage('login.php'); 
    exit(); 
} 

第2のデータベースはSybaseであり、アカウント情報を格納します。ここからリストとアカウント情報を取得するには、ユーザークラスの資格情報が必要です。私は、アカウントクラスは、次に行うべきだと思うが、それを行うための最善の方法はないと思う。多分このような何か...

$sybase = new db('sybase'); 

$account = new account($sybase); 

$account_list = $account->getList($user->info); 

する$ user->は情報私は、アカウントのテーブルに必要な資格情報と情報の推測配列され、またはこれについて行くには良い方法はありますか?

編集デシベルクラスの例に

config.db.php

$config_array = array(); 

$config_array[ 'mysql' ][ 'dsn' ] = "mysql:host=localhost;dbname=********;charset=UTF-8"; 
$config_array[ 'mysql' ][ 'user' ] = "********"; 
$config_array[ 'mysql' ][ 'pass' ] = "**************"; 

$config_array[ 'sybase' ][ 'dsn' ] = "odbc:DRIVER={Adaptive Server Anywhere 8.0};***************"; 
$config_array[ 'sybase' ][ 'user' ] = "**********"; 
$config_array[ 'sybase' ][ 'pass' ] = "*********"; 

class.db.php

public function __construct($type) 
{ 
    require 'config.db.php'; 

    $this->type = $type; 

    foreach($config_array[ $this->type ] AS $key => $value) 
    { 
     $this->$key = $value; 
    } 

    try 
    { 
     $this->connection = new PDO($this->dsn, $this->user, $this->pass, $this->options); 
    } 
    catch(PDOException $ex) 
    { 
     log_action("db->" . $this->type, $ex->getCode() . ": " . $ex->getMessage()); 
     $this->error = true; 
    } 
    return $this->connection; 
} 

を含むように、以下のようなものが意味を成しています?

class User() 
{ 
    public function getAccountList() 
    { 
     $this->Account = new Account(new Database('sybase')); 
     return $this->Account->list($this->userid); 
    } 
} 

はまた、アカウントは、ページ上の異なる「タブ」になります異なるセクション(すなわち、歴史&ノート、金融取引、ドキュメントを)持っています。それらの各クラスもクラスにする必要がありますか?おかげさまで

+0

このシナリオでは、ユーザーとアカウントの違いはわかりません。彼らは同じものではありませんか?または、ユーザーがログインしている人で、アカウントがアクセスしようとしているものですか? –

+0

ユーザはログインした人だけです.useridとpassはwebserverのmysqlに保存されています。レジストリなし - ユーザーを設定し、2番目のデータベースの資格情報を与えます。アカウント情報(2番目のデータベース)はリモートサーバのsybaseに格納されています – bdscorvette

+0

これは意味があります。私の仕事は最近のコーディングよりもアカウント管理が多いので、私は "アカウント"と "ユーザー"を同じものと考える傾向があります;-)。 –

答えて

2

のDimitryすることにより、他の解答の二答えとしてまずアップ、:

あなたが失うものにシングルトン青白いを持つことによって得るでしょうもの。プログラムのすべての部分を読み書きできるグローバルオブジェクトが生成されますが、テスト容易性、可読性、および保守性が失われました。

実際にはSingletonオブジェクトがグローバルであるため、関数が(魔法のように)他のコンポーネントに依存しているため、アプリケーション内の単一ユニットを正確に分離することはできません。

あなたはmethod()が実際に例えば(動作するように他のものが必要になる場合があり、userオブジェクトはdbインスタンスを必要とするためにも、ソースコードを見もせず、私が何を伝えることができるので、これは、new user($db)はるかに読みやすいnew user()よります可読性を失いますメソッド/オブジェクトは動作する必要があります。

上記の理由によりメンテナンス性が失われます。関数の "契約"でそれを見るよりも、シングルトンを介してどのコンポーネントが挿入されているかを知ることは難しく、将来あなたや他の開発者がコードを読んでリファクタリングすることは難しいでしょう。サイドノートとして


、私が今からこの規則を使用することがあります、アッパーケースに入れ、その最初の文字でClass名に名前を付けるために良い命名規則と考えられています。

トップから始めましょう。 Dbオブジェクトの可能な状態は2つあり、MysqlDbSybaseDbです。これは多態性を必要とします。 抽象クラスDbと、2つのコンクリートクラスMysqlDbSybaseDbを継承しています。正しいDBオブジェクトのインスタンス化が

class DbFactory { 

    private $db; 

    /** 
    * Create a new Db object base on Type, and pass parameters to it. 
    * 
    * @param string $type Type of database, Mysql or Sybase. 
    * @param string $dsn The DSN string corresponding to the type. 
    * @param string $user User credential 
    * @param string $pass Password credential 
    * 
    * @return Db 
    */ 

    public function create($type, $dsn, $user, $pass) { 
     if (!is_a($this->db, "Db")) { 
      $type  = $type . "Db"; 
      $this->db = new $type($dsn, $user, $pass); 
     } 

     return $this->db; 
    } 
} 

abstract class Db { 

    /** 
    * @param $dsn 
    * @param $user 
    * @param $pass 
    */ 
    public function __construct($dsn, $user, $pass) { 
     $this->db = new PDO("$dsn", $user, $pass); 
     $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
    } 
} 

class MysqlDb extends Db { 

    /* 
    * More specific, Mysql only implementation goes here 
    */ 
} 

class SybaseDb extends Db { 

    /* 
    * More specific, Sybase only implementation goes here 
    */ 
} 

工場の責任である今、あなたはアカウントのリストを取得するための責任が誰であるか、自問してみてくださいする必要がありますか?確かに彼らは自分自身をフェッチするべきではありません(データベースから独自のデータをフェッチするのはユーザーの責任ではありません)。これらのアカウントを取得するにはUserの責任SybaseDbを使用しています。実際に

Userは仕事に以下を必要とします。

  • Sybaseデータベースの接続 - アカウントリストをフェッチします。 DbFactoryインスタンスを渡します。インスタンスがすでにインスタンス化されている場合はインスタンスを簡単に取得でき、存在しない場合はインスタンス化できます。
  • 状態情報(ログイン状態、ユーザーID、ユーザー名など)。 は、このデータを設定に

Userは、それがそれに動作するために必要である、責任を負いません。

のでUserコンストラクタは、(「ID」と「名前」フィールドを想定して)次のようになります。

User::__construct($id, $name, DbFactory $factory); 

UserAccountオブジェクト配列を開催するフィールド$accountsを、持っています。この配列にはUser::getAccounts()メソッドが設定されます。

+0

ありがとうございます。非常に有益。私は自分の責任について何を言っているのか、そして彼らが働く必要があるのか​​を理解していると思います。ユーザーは自分のアカウントを取得します。アカウントは自分自身を取得しませんでした。しかし、確かにアカウントもオブジェクトでなければなりませんか?アカウントには、金融取引、履歴、メモ、請求書などがあります。 – bdscorvette

+0

確かに。ユーザは** Account **オブジェクトの配列**である '$ accounts'プロパティを保持します**。これは、どのアカウントがどのユーザーに属しているかを簡単にカプセル化するのに役立ちます。 –

-1

私は、アカウントをユーザークラスのメンバーにします。 「ユーザーにはアカウントがあります。

また、クラスについて言えば、2つのDBがシングルトンであることを確認して、ではなくgetInstance()で取得してください。

+0

ありがとうございます。私は、より正確に言うと、ユーザー**はさまざまなアカウントに**アクセスしていると思います。たとえば、管理者はすべてのアカウントにアクセスでき、クライアントと従業員(営業担当者など)は限られた範囲のアカウントにアクセスできます。これらの範囲または他のデータベースへの制限は、 'クライアントコード'によって強制されます。私はdbクラスの例を含めるようにOPを編集しています。 getInstance()を使ってシングルトンに移動することで何が得られるかを理解するのを手伝ってください。(シングルトンが何であるか理解していると思います。) – bdscorvette

+0

シングルトンでうまくいきません。私はあなたにそれを与えることができます。 –

関連する問題