<?php define('ABSPATH', dirname(__FILE__)); //Absolute path to index /* * Method 1 * Dependency Injection */ class Config{ private $_config = NULL; private $_filepath = NULL; public function __construct($filepath){ $this->_filepath = $filepath; $this->load(); } private function load(){ if ($this->_config === NULL){ if (!file_exists($this->_filepath)){ throw new Exception('Configuration file not found'); }else{ $this->_config = parse_ini_file($this->_filepath); } } } public function get($key){ if ($this->_config === NULL){ throw new Exception('Configuration file is not loaded'); } if (isset($this->_config[$key])){ return $this->_config[$key]; }else{ throw new Exception('Variable ' . $key . ' does not exist in configuration file'); } } } function getLost($where, $why, $who){ //do smth } try{ $config = new Config(ABSPATH . '/app/config.ini'); getLost('here', 'because', $config->get('who')); }catch(Exception $e){ echo $e->getMessage(); } ?>
<?php /* * Method 2 * Config is accessed via static class */ class Config{ private static $_config = NULL; private static $_filepath = NULL; public static function load($filepath){ if (self::$_config === NULL){ self::$_filepath = $filepath; if (!file_exists(self::$_filepath)){ throw new Exception('Configuration file not found'); }else{ self::$_config = parse_ini_file(self::$_filepath); } } } public static function get($key){ if (self::$_config !== NULL){ throw new Exception('Configuration file is not loaded'); } if (isset(self::$_config[$key])){ return self::$_config[$key]; }else{ throw new Exception('Variable ' . $key . ' does not exist in configuration file'); } } } function getLost($where, $why){ $who = Config::get('who'); } try{ Config::load(ABSPATH . '/app/config.ini'); getLost('here', 'because'); }catch(Exception $e){ echo $e->getMessage(); } ?>
<?php /** * Method 3 * Config variable needed is passed as function parameter */ $config = parse_ini_file(ABSPATH . '/app/config.ini'); function getLost($where, $why, $who){ //do smth } getLost('here', 'because', $config['who']); ?>
<?php /* * Mathod 4 * Config is accessed inside a function via global */ $config = parse_ini_file(ABSPATH . '/app/config.ini'); function getLost($where, $why){ global $config; $who = $config['who']; } getLost('here', 'because'); ?>
Какой из этих вариантов является наилучшим решением? Если нет, укажите свой вариант.
Я бы пошел на вариант 1 (инъекция зависимостей).
Вариант 2 использует static
методы, которые, как уже указывалось, являются просто альтернативным способом global
методов. И мы все знаем, что это плохо? правильно?
Вариант 3 не является моим любимым, потому что это недостаточно OOP ;-), но серьезно: что, если вы (или человек, использующий ваш код) хотите изменить формат файла конфигурации?
Вариант 4: global
…
Поэтому в основном мои проблемы с другими вариантами: тестируемость, жесткая связь, глобальная.
Так что вариант 1 есть. Я бы также создал интерфейс для класса config, чтобы вы могли добавить другой класс для своих файлов конфигурации в более поздний момент. Например, вы (или кто-то другой в этом отношении) хотите использовать файлы XML для конфигурации.
Еще одна вещь, которую я бы изменил, – это private
вещи. Если кто-то хочет расширить класс, он не будет иметь доступа к переменным таким образом. Мое эмпирическое правило (не уверен, что все согласны с этим, хотя) только делает private
если вы хотите, чтобы у людей был доступ к нему (например, в какой-то момент он изменится). Опасность использования private
заключается в том, что люди будут обходить его хаками, чтобы делать то, что они хотят.
Узнайте больше о SOLID и просмотрите проводки Google для чистого кода для получения дополнительной информации.
Только мои 2 цента.
Я бы сказал, что первый случай лучше, если вы замените $ config на $ onlyTheStuffThatMattersToThatFunction