oop — Какой предпочтительный способ сделать объект доступным везде в PHP?

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

Я использовал глобальные переменные для них, пока кто-то (с фоном C ++) любезно не указал, что «Вы, вероятно, делаете что-то не так, если вам нужны глобальные переменные».
Он предложил использовать объект состояния, который передается всем функциям, которые в этом нуждаются.
Так я и сделал:

$state = new State();
$state->register('eventManager' , new EventManager());
$state->register('configManager', new ConfigManager());
$state->register('cacheManager' , new CacheManager());
$state->register('pluginManager', new PluginManager());

$state->get('pluginManager')->initialize($state);

Хотя я вижу преимущества этого метода в более динамичных языках, для меня это кажется бессмысленным в (в основном?) Языке без сохранения состояния, таком как PHP, где состояние теряется после завершения загрузки страницы.

Есть ли какая-либо польза от передачи объекта состояния в (в основном) языке без состояний, таком как PHP, имеет ли он какие-либо преимущества по сравнению с другими подходами (то есть системой, основанной на глобальных параметрах), и есть ли лучшие способы справиться с этим?

2

Решение

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

Правильное приложение имеет только ту фазу, где глобальное состояние играет роль: при его загрузке. Запрос, запускающий скрипт, является глобальным, любые данные запроса, отправленные с ним, являются глобальными, и любая конфигурация, которая влияет на приложение и хранится в файле или каком-либо другом подходящем хранилище, является глобальной.

Первый этап должен инициализировать некоторое внедрение зависимости, которое объединяет все части, составляющие приложение. Этот граф объектов будет создан по требованию, когда обработка запроса решит, какая часть кода должна быть вызвана для ответа на запрос.

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

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

Задачей внедрения зависимости будет создание только одного объекта базы данных или нескольких из них. Вам не нужно использовать устаревший «синглтон антипаттерн», потому что у него много недостатков.

Таким образом, в этом сценарии существуют некоторые объекты, существующие в части внедрения зависимостей, которые создаются только один раз и внедряются при необходимости. Эти объекты не обязательно должны быть созданы только один раз, и они не хранятся внутри глобально доступной переменной. Однако что-то должно жить в глобальной переменной, но это только основной объект каркаса и, возможно, контейнер внедрения зависимости, и они никогда не разделяются в оставшемся коде как глобальная переменная — так что это совсем не вредно.

2

Другие решения

Один из способов сделать это с одиночек:

class ConfigManager {
private static $instance = NULL;

public static function getInstance(){
if(self::$instance === NULL) {
self::$instance = new ConfigManager();
}

return self::$instance;
}

private function __construct(){
// Notice that this is private - only getInstance() can call this.
}
}

// When you need it:
$config = ConfigManager::getInstance();

Есть много разных мнений о том, как сделать то, что вы просите — и я сам не думаю, что одиночные игры всегда являются лучшим способом сделать это. Это действительно зависит от вашего варианта использования.

Тем не менее, синглтоны — это всего лишь один общий шаблон для класса, экземпляр которого должен быть доступен везде.

2

По вопросам рекламы [email protected]