OOP PHP新手,指导请求,类间数据共享设计

OOP PHP新手,指导请求,类间数据共享设计,php,oop,Php,Oop,用PHP编写第一个使用类和对象的应用程序。 我有一个DB类,它使用一个字符串来选择适当的配置,因为有多个数据库。我从一个login类开始,但为了交换一个user类,所以我可以做user->isLoggedIn之类的事情,我放弃了这个想法。user类使用MySQL存储用户和登录信息,以及第二个数据库的凭据 $mysql = new db( 'mysql' ); $user = new user( $mysql ); if( !( $user->isLoggedIn() === true )

用PHP编写第一个使用类和对象的应用程序。 我有一个DB类,它使用一个字符串来选择适当的配置,因为有多个数据库。我从一个login类开始,但为了交换一个user类,所以我可以做user->isLoggedIn之类的事情,我放弃了这个想法。user类使用MySQL存储用户和登录信息,以及第二个数据库的凭据

$mysql = new db( 'mysql' );

$user = new user( $mysql );
if( !( $user->isLoggedIn() === true ) )
{
    goToPage( 'login.php' );
    exit();
}
第二个数据库是Sybase,存储帐户信息。我需要来自user类的凭据从这里获取列表和帐户信息。我认为下一个应该是account类,但不确定最好的方法。像这样的事情也许

$sybase = new db( 'sybase' );

$account = new account( $sybase );

$account_list = $account->getList( $user->info );
$user->info是account表所需的凭证和信息的数组,还是有更好的方法

编辑以包含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 );
    }
}

此外,账户有不同的部分(即历史记录和注释、财务交易、文档),这些部分在页面上是不同的“选项卡”。它们中的每一个也应该是一个类吗?

我会让Account成为用户类的成员。“用户有一个帐户”,对吗


另外,谈到类,请确保您的两个DB是单音,并通过
getInstance()
,而不是
\uu construct()
获取它们。首先,作为Dimitry另一个答案的第二个答案:

单身汉给你带来的好处与你失去的东西相形见绌。您得到了一个全局对象,程序的每个部分都可以读取和修改它,但是您失去了可测试性、可读性和可维护性

因为Singleton对象实际上是全局的,所以您无法准确地隔离应用程序中的单个单元(这对于单元测试至关重要),因为您的函数依赖于其他组件,这些组件“神奇地”插入其中

您失去了可读性,因为
method()
实际上可能需要其他东西才能工作(例如,
user
对象需要一个
db
实例,这使得
新用户($db)
新用户()
,因为即使不看源代码,我也可以知道方法/对象需要做什么

由于上述原因,您也会失去可维护性。通过Singleton插入哪些组件比在函数的“契约”中看到它更难,因此,未来您和/或任何其他开发人员阅读和重构您的代码都会更难


作为补充说明,命名
名称时,将其首字母大写被认为是良好的命名约定,从现在起,我将使用此约定

让我们从顶部开始。您的
Db
对象有两种可能的状态,
MysqlDb
SybaseDb
。这需要多态性。您有一个抽象的
Db
,以及继承自它的两个具体的
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
     */
}
现在,您应该问问自己,谁负责获取帐户列表?当然,他们不应该获取自己的帐户(正如用户不应该从数据库获取自己的数据一样)使用
SybaseDb
连接获取这些帐户是
用户的责任

实际上,
用户
需要执行以下操作:

  • Sybase数据库连接-获取帐户列表。我们将把
    DbFactory
    实例传递给它,这样,如果实例已经实例化,我们就可以轻松地获取它,如果没有实例化,我们就可以实例化它
  • 状态信息(登录状态、用户ID、用户名等)
用户
不负责设置此数据,它需要它才能工作

因此
用户
构造函数应该如下所示(假设“ID”和“name”字段):


用户
将有一个字段
$accounts
,该字段将包含
帐户
对象的数组。此数组将填充
用户::getAccounts()
方法。

在这种情况下,我不太理解用户和帐户之间的区别。它们不是一回事吗?或者用户就是登录的人,而帐户就是他们试图访问的东西?用户就是登录的人。userid和pass存储在Web服务器上的mysql中。没有注册表-我们设置了用户并给出了cre第二个数据库的dentials。帐户信息(第二个数据库)存储在远程服务器上的sybase中。这是有道理的。我现在的工作更多的是帐户管理,而不是编码,所以我倾向于将“帐户”和“用户”视为同一件事;-)。谢谢。我想我更准确地说,用户可以访问一系列帐户。例如,管理员可以访问每个帐户,而客户和员工(如销售人员)可以访问有限范围的帐户。对其他数据库的这些范围或限制由“客户机代码”强制执行,让我们调用它。我正在编辑OP以包含db类的示例。请帮助我理解使用getInstance()迁移到singleton会带来什么好处(我想我理解singleton是什么,也许不是)使用singleton不会有什么好处。我可以给你,谢谢。信息量很大。我想我理解你所说的关于他们的责任和他们需要工作的内容。用户将获得他们的帐户。这些账户不会自动更新。但是,帐户肯定也是一个对象吗?账户确实有财务交易、历史记录、票据、发票等。美国
User::__construct($id, $name, DbFactory $factory);