Недавно я начал обновлять свой код API на сервере Apache, используя больше наследования. Поскольку я был немного осторожен, чтобы использовать его в прошлом из-за неопытности. Дело в том, что я заметил, что для каждого экземпляра модели устанавливается новое соединение с базой данных. Поэтому я создал альтернативное соединение с переменной Static для передачи каждой модели. Мой вопрос: вызовет ли несколько подключений к базе данных для каждого нового экземпляра модели проблемы, если я создам подключение, такое как в моем примере ниже, с помощью __construct?
class ApiEnterprises {
protected $db;
private $table;
public function __construct(){
$this->messager = new Messager();
$this->table = 'enterprisetable';
$this->db = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
if ($this->db === NULL || !$this->db) {
// set response code
echo $this->messager->databaseFailed();
}
}
}
class ApiUsers {
protected $db;
private $table;
public function __construct(){
$this->messager = new Messager();
$this->table = 'usertable';
$this->db = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
if ($this->db === NULL || !$this->db) {
// set response code
$this->messager->databaseFailed();
}
}
}
В качестве альтернативы переменная Static будет безопаснее? Как я могу удалить его в методе Controller __destruct.
class Database {
static $connect;
protected static function conn() {
self::$connect = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
return self::$connect;
}
}
class ApiUserController extends Database {
private $user_model;
private $enterprise_model;
public $connection;
public function __construct($data){
$this->connection = parent::conn();
//pass connection to models
$this->user_model = new ApiUsers($this->connection);
$this->enterprise_model = new ApiEnterprises($this->connection);
}
}
Что вам нужно, так это контейнер IoC, но прежде чем вы доберетесь до него, вам нужно спроектировать свои модели таким образом, чтобы они принимали экземпляр базы данных в качестве параметра в конструкторе. Это называется внедрением зависимостей. Все зависимые экземпляры внедряются в новый объект во время его создания.
Поскольку ваш Database бесполезен, я бы не рекомендовал его использовать, но вам следует написать какую-нибудь библиотеку абстракции базы данных или использовать ту, которая уже доступна в Интернете. например EasyDB
Вот пример одной инъекции зависимости:
class ApiEnterprises {
protected $db;
protected $messager;
private $table = 'enterprisetable';
public function __construct(mysqli $db, Messager $messager) {
$this->db = $db;
$this->messager = $messager;
}
}
// mysqli connection somewhere at the start of your application
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
$mysqli->set_charset('utf8mb4'); // always set the charset
// instantiate the model and pass mysqli as an argument
$enterprise = new ApiEnterprises($mysqli, $messager);
Почему вы говорите, что класс базы данных бесполезен? Из двух моих примеров во втором используется dependency injection, поскольку вы можете ясно видеть, что экземпляр подключения передается в модели. //pass connection to models $this->user_model = new ApiUsers($this->connection); $this->enterprise_model = new ApiEnterprises($this->connection);. Также спасибо за ваш ответ, так как теперь я знаю, что второй пример лучше двух.
Да, во втором примере используется внедрение зависимостей, но класс контроллера наследуется от класса базы данных. Ненаследование должно происходить, когда подкласс является частным случаем общего случая, например. Грузовик Volvo наследует от Vehicle. Контроллер не является классом базы данных, поэтому он не должен наследоваться. Кроме того, похоже, что ваш класс базы данных ничего не делает. Помните, что mysqli — это отдельный класс, вам не нужно его оборачивать, если только вы не собираетесь расширять его дополнительными функциями.
Возможно, стоит взглянуть на внедрение зависимостей (например, stackoverflow.com/questions/10064970/php-dependency-injection) и внедрить соединение с базой данных. Это значительно упрощает тестирование (среди прочего).