Опасность объявления нескольких подключений к базе данных в общедоступном __Constructor vs Static Variable Connection

Недавно я начал обновлять свой код 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);
        }
    }

Возможно, стоит взглянуть на внедрение зависимостей (например, stackoverflow.com/questions/10064970/php-dependency-injecti‌​on) и внедрить соединение с базой данных. Это значительно упрощает тестирование (среди прочего).

Nigel Ren 20.12.2020 16:45
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout.
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout.
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для...
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
0
1
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Что вам нужно, так это контейнер 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);. Также спасибо за ваш ответ, так как теперь я знаю, что второй пример лучше двух.

Hmerman6006 20.12.2020 20:01

Да, во втором примере используется внедрение зависимостей, но класс контроллера наследуется от класса базы данных. Ненаследование должно происходить, когда подкласс является частным случаем общего случая, например. Грузовик Volvo наследует от Vehicle. Контроллер не является классом базы данных, поэтому он не должен наследоваться. Кроме того, похоже, что ваш класс базы данных ничего не делает. Помните, что mysqli — это отдельный класс, вам не нужно его оборачивать, если только вы не собираетесь расширять его дополнительными функциями.

Dharman 20.12.2020 20:14

Другие вопросы по теме