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

Хочу полностью отказаться от глобальных переменных. Создаю экземпляр класса DB и нужно к нему обращаться из остальных классов приложения.

На самом деле это может быть не только бд но и другие общие переменные... что то вроде "хранилища" типа как Vuex в Vue.
  • Вопрос задан
  • 436 просмотров
Решения вопроса 1
@0x131315
Пора освоить внедрение зависимостей.
https://m.habr.com/ru/post/350708/comments/#commen...
Это такие штуки, которые сами подставляют в конструктор класса требуемые ему зависимости.
Например можно взять php-di пакет в composer.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
FanatPHP
@FanatPHP
Чебуратор тега РНР
Вопрос сложный.

Правильный ответ: передавать в конструктор класса.
Всякие "хранилища" - это костыли, не сильно лучше жлобалсов.

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

Тут фокус в том, что мы не создаем объекты руками через new.
И мыслим не отдельными объектами, а конкретным функционалом.
В А мы передаем тот функционал, который нам создаст экземпляр объекта Бэ

Самый тупой пример: контроллер принципиально не работает с БД.
С БД работает модель. Но модель мы вызываем из контроллера. Как быть? Вот он твой случай.

И тут нам DI, при создании экземпляра контроллера, и передаст в него нужную модель.
У которой внутри уже будет подключение к БД.
И которая нам вернет какой-нибудь DTO, создав его сама.

То есть в ООП мы на самом деле мыслим не отдельными классами, а функционалом. Не "я хочу такой объект создать в А", а "я хочу такой-то функционал получить в А"
А этот функционал уже сам говорит DI, какой функйионал, какие зависимости ему в свою очередь нужны для работы. DI их прилежно создает. И так по цепочке до самых первичных объектов типа соединения с БД, логгера и пр.
Ответ написан
@rPman
Если нужно полностью исключить глобальные переменные, необходимо везде где это нужно носить с собой (указывать в вызовах функций) базовый объект, определяющий контекст выполнения.

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

class Main
{
  public $db; // само собой можно геттеры сеттеры делать или сами методы по работе с базой тут определить
}
class Work
{
  function __construct($main)
  {
    $this->main=$main;
  }
  function do()
  {
    $this->main->db->connect(...)
  }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы