组织PHP OOP类以使用DB

时间:2013-08-04 09:58:52

标签: php database oop

今天我有一个非常奇怪的类结构的PHP项目。像这样:

db_base
  `-- db_base_ext extends db_base
        +-- module_1 extends db_base_ext
        +-- module_2 extends db_base_ext
        .   ...
        +-- module_N extends db_base_ext
        `-- db_user extends db_base_ext

class_1
  `-- submodule_1_1 extends class_1

db_base连接到__construct()中的db,并有一些辅助方法。

执行的例子:

$db = new db_user();
$user = new user($db);
unset($db);

$db = new module_2();

我不喜欢在这段代码中我们连接到DB两次并且整个类结构不是很好。

我怎样才能让它变得更好?我的意思是只创建一个数据库实例,并在此工作之后使用任何类(对应于DB)?

单身人士模式会对此有好处吗?

3 个答案:

答案 0 :(得分:4)

你的问题在于,你的结构,

module_2 extends db_base_ext
db_user extends db_base_ext
submodule_1_1 extends class_1

他们都破坏了Single Responsibility PrincipleLiskov Substitution Principle

  

我怎样才能让它变得更好。我的意思是只创建一个数据库实例   可以使用任何类(对应于DB)吗?

Dependency injection是要走的路。您将实例化一个数据库实例,并且您的所有类将共享相同的 $db实例。

final class MySQLPDO extends PDO
{
    public function __construct(array $params)
    {
      parent::__construct(sprintf('mysql: host=%s; dbname=%s', $params['host'], $params['database']), $params['username'], $params['password']);

      $this->setAttribute(parent::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES UTF8');
      $this->setAttribute(parent::ATTR_ERRMODE, parent::ERRMODE_EXCEPTION);
      $this->setAttribute(parent::ATTR_EMULATE_PREPARES, false);
      $this->setAttribute(parent::ATTR_DEFAULT_FETCH_MODE, parent::FETCH_ASSOC);

    }
}

$db = new MySQLPDO(array(
     'host'     => 'localhost',
     'database' => 'foo',
     'username' => 'root',
     'password' => '',
));
$user = new User($db);

$module = new Module1($user);
$foo = new Foo($db);

那么,你会在这里获得什么?重用能力和测试能力。


注意,你应该避免使用Singleton,因为它们会引入另一种形式的全局状态,这对单元测试来说是不利的。

答案 1 :(得分:2)

使用正确的类名

首先,我注意到项目中的类被命名为函数。如果项目试图使用PEAR命名约定,它应该正确。

使模块独立于数据库类

您应该从db_base_ext类断开模块。如果模块需要访问数据库实例,则可以使用构造函数参数或setter提供。它不应该直接扩展类。

$module = new Module($database);

答案 2 :(得分:-2)

您应该考虑为数据库类使用单例模式。

Take a look here for a tutorial。 它使用PDO进行通信,但也应该对mysqli或其他类型有效。