5

クラスとオブジェクトを利用する初めてのアプリケーションを PHP で作成します。複数のデータベースがあるため、文字列を使用して適切な構成を選択する DB クラスがあります。私はログイン クラスから始めましたが、user->isLoggedIn を実行できるように、ユーザー クラスと引き換えにそのアイデアを削除しました。ユーザー クラスは、ユーザーとログイン情報、および 2 番目のデータベースの資格情報を格納する MySQL を使用します。

$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->info は配列であり、アカウント テーブルに必要な資格情報と情報を推測しますか、それとももっと良い方法がありますか?

db クラスの例を含めるように編集

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 );
    }
}

また、アカウントには、ページ上の異なる「タブ」となるさまざまなセクション (つまり、履歴とメモ、金融取引、ドキュメント) があります。それらのそれぞれもクラスにする必要がありますか?

4

2 に答える 2

2

まず、Dimitryによる他の回答に対する二次的な回答として:

Singleton を使用することで得られるものは、失うものに見劣りします。プログラムのすべての部分が読み取りおよび変更できるグローバル オブジェクトを取得しますが、テスト容易性、可読性、保守性は失われます。

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

method()実際に機能するために他のものが必要になる可能性があるため、可読性が失われます(たとえば、userオブジェクトにはdbインスタンスが必要です。これにより、ソースコードを見なくてもメソッド/オブジェクトが機能する必要があることがわかるため、new user($db)より読みやすくなります。new user()

上記の理由からも保守性が失われます。シングルトンを介してどのコンポーネントが挿入されているかを判断するのは、関数の「コントラクト」で確認するよりも困難です。そのため、将来、あなたや他の開発者がコードを読んでリファクタリングするのが難しくなります。


Classちなみに、最初の文字を大文字にして名前を付けるのが良い命名規則と考えられているので、今後はこの規則を使用します。

上から始めましょう。DbオブジェクトにMysqlDbは との 2 つの状態がありますSybaseDb。これにはポリモーフィズムが必要です。抽象クラスDbと 2 つの具象クラスがMysqlDbあり、それをSybaseDb継承しています。正しい 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);

には、オブジェクトの配列を保持するUserフィールドがあります。この配列には、メソッドが取り込まれます。$accountsAccountUser::getAccounts()

于 2012-11-02T20:48:38.213 に答える
-1

Account を User クラスのメンバーにします。「ユーザーアカウントを持っています」ですよね?

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

于 2012-11-02T12:16:39.510 に答える