Intereting Posts

организация классов PHP 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 подключается к db в __construct() и имеет некоторые вспомогательные методы.

пример выполнения:

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

Мне не нравится, что в этом коде мы соединяемся с БД дважды, а вся структура классов не очень хороша.

Как я могу сделать это лучше? Я имею в виду создать только один экземпляр БД и после этой работы с любым классом (соответствующим БД)?

Будет ли образец синглэтона хорош для этого?

Ваша проблема заключается в том, что ваши структуры,

 module_2 extends db_base_ext db_user extends db_base_ext submodule_1_1 extends class_1 

все они нарушают принцип единой ответственности и принцип замены Лискова .

Как я могу сделать это лучше. Я имею в виду создание только одного экземпляра DB и после этой работы с любым классом (соответствующим БД), возможно?

Запуск зависимости – это путь. Вы должны создать экземпляр одного экземпляра db, и все ваши классы будут иметь один и тот же экземпляр $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); 

Итак, что бы вы получили здесь? Возможность повторного использования и способность тестировать.


Обратите внимание: вам следует избегать синглтона, поскольку они вводят другую форму глобального состояния, что плохо для целей модульного тестирования.

Использовать имена классов

Во-первых, я заметил, что классы в проекте называются как функции. Если проект пытается использовать соглашения об именах PEAR, он должен сделать это правильно.

  • Соглашения об именах (Руководство по груше)

Сделать модули независимыми от класса базы данных

Вы должны отключить модули от класса db_base_ext . Если модуль нуждается в доступе к экземпляру базы данных, он может быть предоставлен с использованием аргументов или сеттеров конструктора. Он не должен распространять класс напрямую.

 $module = new Module($database); 

Вы должны подумать об использовании шаблона singleton для вашего класса DB.

Посмотрите здесь учебник . Он использует PDO для связи, но должен также быть действительным для mysqli или других типов.