Intereting Posts

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

Много раз я слышал, чтобы избежать статических классов, потому что они будут вставлять зависимости, которые сделают ваш код непригодным для использования в других проектах и ​​не позволят ему его протестировать .

Допустим, у нас есть типичная class DB для доступа к базе данных, если такой класс является static мы могли бы называть его везде в нашем коде:

 DB::execQuery(...); 

но это создает зависимости, поэтому давайте сделаем класс базы данных НЕ статическим, в таком случае мы будем иметь где-то в нашем коде:

 $db = new DB(); 

и тогда мы могли бы позвонить в наш код

 $db->execQuery(...); 

Но теперь, когда мы используем $db внутри function нам нужно каждый раз сначала объявить ее так

global $db;

Есть ли способ обхода этого?

Один из способов может заключаться в том, чтобы $db объект $db в класс, который его использует, но мне пришлось бы вводить его во все классы, которые его используют, это смехотворно, статический класс будет намного быстрее работать с и меньше кода для записи. Я что-то упускаю?!

Related of "PHP избегает статических классов, чтобы избежать зависимостей, но мне нужно использовать глобальные везде"

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

 class MyClass { protected $_db; // DB Connection public function __construct($db) { $this->_db = $db; } public function foo() { $this->_db->query('...'); } } 

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

  • Если Синглтоны плохие, то почему Service Container хорош?
  • Является ли хорошей практикой, чтобы контейнер DI заменил глобальный объект реестра $?

Наличие контейнера DI позволяет использовать статические методы в ваших классах, таких как DI_Container::get('db') . Он очень похож на global или некоторые другие статические вызовы .. но в этом случае DI_Container содержит специальные методы, которые позволяют принимать дополнительные меры во время тестирования и в других обстоятельствах .. устранение некоторых «злобности» глобального.

В дополнение к ответу Майка Б, я бы указал, что неправильный дизайн в вашем коде: «мы могли бы называть его везде, где в нашем коде».

Фактически, база данных должна использоваться только вашей моделью или малой частью вашего приложения, которая должна знать о базе данных. Поэтому эти классы должны знать, что есть база данных, и использовать ее как зависимость (передается через конструктор, как сказал Майк Б).

Но остальная часть вашего приложения не должна заботиться о базе данных, ее следует заботиться только о модели. Сосредоточьтесь на рефакторинге и сборе всего кода, который обращается к базе данных в классах модели.

Таким образом, ваше приложение будет иметь слой модели, который имеет зависимость: объект / соединение с базой данных. Остальная часть вашего приложения будет использовать модель, независимо от того, что происходит в модели, ни в одном из бизнеса Controller / View.

Наслаждайтесь рефакторингом.