Доброе время суток!
Я совсем недавно начал изучение php, так что прошу сильно не ругать за "ламерский" вопрос.
Ситуация такая, начал писать проект для друзей, чтоб заодно научится OOP php, и сразу же возник вопрос о правильном class DB. У меня существует несколько таблиц, в которых хранится разная инфа, допустим, users, product. Есть class DB, в котором происходит соединение с базой по mysqli_ в конструкторе и написаны методы select, query..
Есть class Users в котором описаны свойства и методы моих users. И я сейчас, чтоб использовать мой класс DB, сделал class Users extends DB {....} и что-то мне подсказывает, что это неверно, ведь в другом классе, который будет работать с DB, если я тоже присвою DB, то создадутся два соединения..
Хотелось бы понять раз и навсегда, как правильно самому с нуля писать OOP соединения?
@hell0w0rd задача была убрать многократное инициализирование DB, синглтон как раз подходит для этой задачи на все 146%. А то что вы написали ниже - и есть бред который еще сильнее запутает новичка.
Во-первых, как уже правильно посоветовали - используйте паттерн синглтон, для того, чтобы у класса был только 1 объект.
Во-вторых, сначала опишите архитектуру вашего приложения. Как я понимаю, user и product - это у вас модели. Над моделями проводятся какие-то манипуляции (заполняется данными, редактируются данные или что-то еще), затем новое состояние модели надо записать в базу.
Как раз-таки для реализации вот этой прослойки между моделями и базой я рекомендую почитать про такие паттерны, как Active Record и DataMapper.
@SOKOJI ничего подобного не нужно контролировать. Я могу хоть 25 соединений открыть, никто подобного не запрещает.
Чтобы избежать создания второго соединения не нужно наследоваться от класса. Класс должен быть зависимостью, вот и все
Во первых используйте паттерн singleton (в простонародье - одиночка), а помимо этого не забудте, что коннект должен быть всегда лишь один
Во вторых, все возможные параметры - в конфиг
В третьих, делайте проверку указываемых параметров на случай "умного" пользователя или отсутствие коннекта
В четвертых, сделайте нормальный обработчик ошибок запросов
В пятых, внедрите туда защиту (экранирование, к примеру) по запросу метода
Ну и конечно серьезные функции, которые клиент не должен юзать, следует сделать protected
Поддержу сингалтон:
При инициализации вы производите подключение к БД DB::connect($host, $port, ....);
good practice: инициализировать подключение при первом обращение к БД
Дальше в нужных местах проекта (модели, контроллеры) уже выполняете запрос: $result = DB::query($sql_query, $attr);
Сколько же бреда написано.
Вам не нужен синглтон. Вы должны четко разделять грань между тем как данные представлены в php и то, откуда они берутся. Для этого вы можете, например создать класс DB и Repository, который будет принимать экземпляр DB и название таблицы. Вроде как это называется ActiveRecord.
Выгода - вы можете создать еще один Repository, который будет принимать, например, APIBlaBla, и работать с апи какого-то сайта так, будто бы это ваша база данных.
А использование синглтонов в таких вещах, как работа с базами данных/кеш/роутинг/шаблонизация - нарушает все принципы SOLID, ваше приложение будет жестко связано по рукам и ногам.
Не согласен ни про синглтон, ни про active record, ни про связанность по рукам и ногам. ActiveRecord вообще можно как угодно написать, была бы фантазия - у всех свой ActiveRecord, грубо говоря. Используя ваш совет можно написать кучу лапши, поправьте если я не прав.
простите, вы новичку предлагаете сразу active record писать?)
а вообще правильно примерно так:
Класс конструктор запроса, так называемый sql builder
Класс строитель из sql builder, в запрос для выбранного провайдера БД
Собственно обертка над провайдером (pdo, mysql, mysqli,...), выполняющая запрос и возвращающая результат.
Последней 2 пункта, по желанию можно объединить в один класс
@hell0w0rd в данном контексте класс синглтон лишь подразумевает наличие одного объекта в памяти и не более, он не подразумевает базовый класс, при чем тут вообще базовый класс? У вас может быть базовый класс new engine() к примеру, а использовать внутри него уже синглтон никто не мешает же.