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

bds*_*tte 5 php oop

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

$mysql = new db( 'mysql' );

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

第二个数据库是Sybase并存储帐户信息.我需要来自用户类的凭据才能从此处获取列表和帐户信息.我认为一个帐户类应该是下一个但不确定最好的方法.这样的事可能......

$sybase = new db( 'sybase' );

$account = new account( $sybase );

$account_list = $account->getList( $user->info );
Run Code Online (Sandbox Code Playgroud)

$ 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' ] = "*********";
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

像下面这样的东西有意义吗?

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

此外,帐户有不同的部分(即历史和笔记,财务交易,文档),这些部分将在页面上显示不同的"标签".每个人都应该成为一个班级吗?

Mad*_*iha 2

首先,作为 Dimitry 另一个答案的次要答案:

拥有 Singleton 所获得的东西与你失去的东西相比显得苍白无力。你得到了一个全局对象,程序的每个部分都可以读取和修改它,但你失去了可测试性、可读性和可维护性。

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

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

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


附带说明一下,Class用首字母大写命名名称被认为是很好的命名约定,从现在开始我将使用此约定。

让我们从顶部开始。您的Db对象有 2 种可能的状态,MysqlDbSybaseDb。这就需要多态性。您有一个抽象Db和两个具体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
     */
}
Run Code Online (Sandbox Code Playgroud)

现在您应该问自己,谁负责获取帐户列表?当然,它们不应该获取自己(就像用户没有责任从数据库获取自己的数据一样)。使用连接User获取这些帐户是的责任。SybaseDb

事实上,需要User满足以下条件才能工作:

  • Sybase 数据库连接 -获取帐户列表。我们将把DbFactory实例传递给它,这样我们就可以轻松地获取该实例(如果它已经实例化),如果没有则实例化它。
  • 状态信息(登录状态、用户 ID、用户名等)。

User负责设置此数据,它需要它才能工作。

所以User构造函数应该如下所示(假设“ID”和“name”字段):

User::__construct($id, $name, DbFactory $factory);
Run Code Online (Sandbox Code Playgroud)

User有一个字段$accounts,其中包含一个对象数组Account。该数组将填充一个User::getAccounts()方法。