• Как сделать автоподключение базы данных?

    @alexey_novorisov_89 Автор вопроса
    Vitsliputsli, почему обёртка выглядит лишней? Просто я действовал по принципу, что в каждой моделе подключать ПДО по новой было бы лишним (как один из видов SRP в моем неопытном понимании), вот и вынес ее в отдельный класс.
    Т.е. должна быть обёртка для pdo, а не mysql.

    Да, я ошибся в формулировке, прошу прощения за ввод в заблуждение. Собственно, "строковая константа с названием СУБД" подразумевала разные подключения в пдо (там же не одно слово заменить, все-таки есть нюансы).
    По поводу второго абзаца: я, если честно, очень долго вожусь с пониманием как архитектуры, так и принципов ООП (не просто голимое заучивание, а активное применение, чтобы на собеседовании было что показать банально), но в интернете ужасно мало информации с более практическими (реальными бекендовыми) примерами. Я, собственно, если бы не пытался отточить это дело, даже не парился бы по поводу этого вопроса, но я хочу разобраться, как и почему лучше, чтобы не приучать себя к неправильному.
    Зависимости должны внедрятся - DI, вы же хотите их создать внутри (service locator, например), это антипаттерн.

    Я, насколько понял из прочитанного в интернете, попытался инъекцию:
    <?php
    namespace App\Models;
    
    use App\Models\Interfaces\iDatabase;
    
    class Cities
    {
        private $db;
    
        public function __construct(iDatabase $db = null)
        {
            $this->db = $db ?? DEFAULT_DB_CONNECTION;
        }
    }


    Моя логика следующая: есть одна единственная база данных mysql, ничего нового я дополнять не планирую, потому что проект учебный, но следует оставить плацдарм для масштабирования системы (ну вот а вдруг (+ принцип открытости-закрытости)), следовательно нужно сделать так, чтобы подключение было не жестким, а как бы в зависимости от ситуации. Исходя из того, что пока что я использую только mysql, то каждый раз при, например, создании объекта условной таблицы выше можно было написать:
    <?php
    namespace App\Controllers;
    
    use App\Models\Cities;
    
    class RegistrationController
    {
        public function test()
        {
            $cities = new Cities();
        }
    }

    а не
    <?php
    namespace App\Controllers;
    
    use App\Models\Cities;
    use App\Models\MysqlDB
    
    class RegistrationController
    {
        public function test()
        {
            $cities = new Cities(new MysqlDB());
        }
    }

    Для решения этой проблемы я и сделал в конструкторе поле подключения БД изначально пустым, чтобы он автоматом подключался к дефолтной. Можете, пожалуйста, объяснить, почему это считается плохой практикой?
  • Как сделать автоподключение базы данных?

    @alexey_novorisov_89 Автор вопроса
    Vitsliputsli, константы потому что я просто не знаю, чего еще написать в файле конфига, чтобы не открывать его как обычный текстовый и функциями в массив строчки конфигурации переделывать.

    Вот примеры.
    Класс с подключениями к разным базам (пока там только одна, большего и не надо):
    <?php
    namespace App\Models;
    
    class DatabaseConnection
    {
        public function mysqlConnection($host, $dbName, $login, $password): \PDO
        {
            return new \PDO("mysql:host=$host;dbname=$dbName", $login, $password,
                [
                    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
                    \PDO::ATTR_EMULATE_PREPARES   => false
                ]
            );
        }
    }


    Класс для Мускла:
    <?php
    namespace App\Models;
    
    use App\Models\Interfaces\iDatabase;
    use App\Models\DatabaseConnection;
    
    class MySQLDB implements iDatabase
    {
        public $dbConnection;
        private $query;
        
        public function __construct($host = 'localhost', $dbName = 'marketplace', $login = 'root', $password = 1111)
        {
            $this->dbConnection = (new DatabaseConnection)->mysqlConnection($host, $dbName, $login, $password);
        }
    
        /**
    	 * SQL query into MySQL DB
    	 * @param array query string
         * @param array placeholders
    	 * @return \PDOStatement
    	 */
    
        public function dbQuery(string $queryString, array $prepareData = NULL): \PDOStatement
        {
            if ($prepareData) {
                return $this->preparedQuery($queryString, $prepareData);
            }
            
            return $this->simpleQuery($queryString);
        }
    
        /**
    	 * SQL prepared query
    	 * @param array query string
         * @param array array with placeholders
    	 * @return \PDOStatement
    	 */
    
        private function preparedQuery(string $queryString, array $data): \PDOStatement
        {
            $this->query = $this->dbConnection->prepare("$queryString");
            $this->query->execute($data);
            
            return $this->query;
        }
    
        /**
    	 * Simple SQL query
    	 * @param array query string
    	 * @return \PDOStatement
    	 */
    
        private function simpleQuery(string $queryString): \PDOStatement
        {
            $this->query = $this->dbConnection->query("$queryString");
            return $this->query;
        }
    }

    И для примера модель, которая отвечает за таблицу 'cities' в базе данных (нужна только для регистрации в данный момент)
    <?php
    namespace App\Models;
    
    use App\Models\Interfaces\iDatabase;
    
    class Cities
    {
        private $db;
    
        public function __construct(iDatabase $db = null)
        {
            $this->db = $db ?? DEFAULT_DB_CONNECTION; // ВОТ ТУТ
        }
    
        public function getAllCities(): array
        {
            return $this->db->dbQuery("SELECT * FROM cities")->fetchAll();
        }
    }


    Где капсом я написал "ВОТ ТУТ" должно осуществляться подключение, но так как вариант с константой отпал, эта строка нерабочая.
    Ну а файл с конфигом нет смысла показывать, там раньше была константа DEFAULT_DB_CONNECTION в который хранился объект дефолтной базы (mysql), а сейчас все пусто.
  • Как сделать автоподключение базы данных?

    @alexey_novorisov_89 Автор вопроса
    Vitsliputsli, объект.
    Если честно, по поводу примеров, их нужно было бы слишком много.
    Мой вопрос заключается в том, как сделать так, чтобы не подключать в каждой моделе модель конкретной БД (Мускл, постгре и т.д), а сделать что то общее?

    Или просто сделать константу со значением конкретной бд ('mysql', 'postgres' и так далее) и if-ами в конструкте работы с бд разобрать ее и вернуть объект в зависимости от значения?