在PHP中编写第一个使用类和对象的应用程序。 我有一个DB类,它接受一个字符串来选择适当的配置,因为有多个数据库。我从一个登录类开始,但是为了交换用户类而划掉了这个想法,所以我可以使用user-> isLoggedIn。用户类使用MySQL来存储用户和登录信息,以及第二个数据库的凭据。
$mysql = new db( 'mysql' );
$user = new user( $mysql );
if( !( $user->isLoggedIn() === true ) )
{
goToPage( 'login.php' );
exit();
}
第二个数据库是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 );
}
}
此外,帐户有不同的部分(即历史记录和笔记,财务交易,文档),这些部分将在页面上显示不同的“标签”。是否每个人都应该成为一个班级?
答案 0 :(得分:2)
首先,作为Dimitry的另一个答案的第二个答案:
通过让Singleton对你失去的东西苍白而获得的东西。您将获得一个全局对象,程序的每个部分都可以读取和修改,但您失去了可测试性,可读性和可维护性。
因为Singleton对象实际上是全局的,所以你无法准确地隔离应用程序中的单个单元(这对于单元测试至关重要),因为你的函数依赖于“神奇地”插入其中的其他组件。
您失去了可读性,因为method()
实际上可能需要其他工作(例如,user
对象需要db
实例,这使得new user($db)
比new user()
更具可读性Class
,因为即使不查看源代码,我也可以告诉方法/对象需要工作的内容。
由于上述原因,您将失去可维护性。通过Singleton分配哪些组件比在函数的“契约”中看到它更难,因此,未来您和/或任何其他开发人员将更难以阅读和重构您的代码。 / p>
作为旁注,我认为命名
Db
名称的首字母大写是一个很好的命名约定,我将从现在开始使用这个约定。
让我们从顶部开始。您有MysqlDb
个对象,SybaseDb
和Db
有两种可能的状态。这需要多态性。您有一个抽象类MysqlDb
,以及两个继承自它的具体类SybaseDb
和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
*/
}
。正确的Db对象的实例化是工厂
User
现在您应该问问自己,谁负责获取帐户清单?当然,他们不应该自己取得(因为用户没有责任从数据库中获取自己的数据)。 SybaseDb
负责获取这些帐户使用 User
连接。
事实上,DbFactory
需要以下工作:
User
实例传递给它,以便我们可以轻松获取实例(如果它已经实例化),如果没有实例化它。 User
不对设置此数据负责,需要以便工作。
因此User::__construct($id, $name, DbFactory $factory);
构造函数应如下所示(假设为“ID”和“name”字段):
User
$accounts
将有一个字段Account
,该字段将包含 User::getAccounts()
个对象数组。该数组将使用{{1}}方法填充。
答案 1 :(得分:-1)
我将Account作为User类的成员。 “用户拥有帐户”,对吧?
另外,谈到课程时,请确保您的两个数据库是单身人士,并通过getInstance()
而不是__construct()
获取。