Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Sposób na GLOBALNY konfig aplikacji
Forum PHP.pl > Forum > PHP > Object-oriented programming
LowiczakPL
Witam

mam pytanie co sądzicie o takim sposobie rozwiązania na globalną konfigurację aplikacji

Klasa kontrolera konfiguracji
  1. <?php
  2.  
  3. namespace Core;
  4.  
  5. final class Config {
  6.  
  7. public static $config = array();
  8.  
  9. public static function getValue($module, $var) {
  10. if (isset(static::$config[$module][$var])) {
  11. return static::$config[$module][$var];
  12. }
  13. else {
  14. include_once('conf/conf.php');
  15. static::$config = $configs;
  16. return static::$config[$module][$var];
  17. }
  18. }
  19.  
  20. }



plik z konfiguracją

  1. <?php
  2.  
  3. switch (ENVIRONMENT) {
  4. case 'development':
  5. $configs['app']['url_website'] = 'http://testowa.rr/';
  6. $configs['app']['debug'] = 'on';
  7. break;
  8. case 'production':
  9. $configs['app']['url_website'] = 'http://mojadomena.pl/';
  10. $configs['app']['debug'] = 'off';
  11.  
  12. break;
  13. default:
  14. exit('Aplikacja nie działa poprawnie, ustaw tryb pracy.');
  15. }
  16.  
  17. $configs['app']['url_ogloszenia'] = $configs['app']['url_website'].'ogloszenia/';
  18. $configs['app']['router_rejestruj'] = 'rejestruj.html';
  19. ...
  20.  


Użycie konfiguracji w klasach

  1. <?php
  2. namespace Controllers;
  3.  
  4. use Helpers\Url;
  5. use Core\Config;
  6.  
  7. public function mojeKonto()
  8. {
  9. ...
  10. Url::redirect(Config::getValue('users','router_mojekonto'));
  11. }
  12.  


vokiel
Kilka uwag:
- Metoda getValue() nie sprawdza czy klucz istnieje po wczytaniu konfiguracji (blok else).
- Zmieniłbym nazwę getValue() na krótsze get() - wiadomo, że chodzi o wartość dla klucza.
- Rozbijasz parametry na $moule i $var - IMHO zbędne, ale jeśli już tak robisz, to każdy moduł powinien być innym plikiem konfiguracyjnym.
- W pliku konfiguracyjnym nie definiujesz na początku zmiennej $configs.
- W ogóle to zwracaj tablicę bez definiowania nazwy zmiennej (patrz przykład poniżej) i przypisuj ją przez
  1. static::$config = require_once('conf/conf.php');

- Proponuję rozszerzyć to o poszukiwanie w ścieżce, tak aby można było pobrać pojedynczy, zagnieżdżony element np:
  1. Config::get('users.default.account.name');


config.php
  1. <?php
  2. return [
  3. 'default' => [
  4. 'account' => [
  5. 'name' => 'test',
  6. 'email' => 'test@example.pl',
  7. ],
  8. 'other' => [
  9. 'foo' => 'bar',
  10. ],
  11. ],
  12. ];

- Ostatnia rzecz, proponuję pójść w kierunku DI zamiast globalnego singletona, dzięki takiemu podejściu testowanie będzie o wiele łatwiejsze.
LowiczakPL
Podoba mi się poszukiwanie po ścieżce, wizualnie lepiej wygląda, podobało mi się bardzo w Laravelu a nie zaimplemetowałem tego u siebie nie wiem czemu.

Co do Di, nie użyłem w tym przypadku bo łatwiej było mi zaimplementować Static, nigdy nie pisałem testów więc nie widziałem w tym problemu.

Jednak jak ktoś wytknie palce lepiej widać, nazwa zmiennej tablicy faktycznie jest zbędna.
com
i co najważniejsze nie rób tego tak:
  1. else {
  2. include_once('conf/conf.php');
  3. static::$config = $configs;
  4. return static::$config[$module][$var];
  5. }


Bo uzależniłeś teraz Twój config od jedynej słusznej implementacji z tablicą w lokalizacji conf/conf.php, co pewnie nawet nie działa bo będzie szukał tego lokalnie tam gdzie będziesz tego używać.
LowiczakPL
Tam jest względna ścieżka ale uprościłem link do minimum na potrzeby prezentacji ale fakt niepotrzebnie, ...

... wezmę się za klasę poprawię ją i zaprezentuję po liftingu.
!*!
Mi tam od razu nasunęło się 10 pytań "a co jeśli..." ;)

- jak masz kilka plików cfg, to przydałaby się metoda która po prostu wgra te pliki (uwzględniając to, co zrobić gdy dany klucz już istnieje)
- jeśli już masz kilka plików, to mogą być one w różnych formatach np ini, json itd.
- skoro już możesz pobierać wartości, to czasami przydaje się wartość domyślna która zostanie zwrócona gdy nie ma odpowiedniego klucza
- a jeśli już możesz pobierać coś z pliku, to możesz go również generować/nadpisać

To tak jakbyś chciał to rozbudować w przyszłości...
LowiczakPL
Przysiadłem dziś do klasy i zastosowałem się do wskazówek, jak to wygląda po zmianach Waszym zdaniem.

plik z konfiguracją ogloszenia.php
  1. <?php
  2.  
  3. /*
  4.   * Ogłoszenia
  5.   */
  6. return [
  7. 'base_path_img' => 'dir/users/ogloszenia/',
  8. 'base_url_img' => 'dir/users/ogloszenia/',
  9. 'img' => [
  10. 'path_thumbs' => 'dir/user/thumbs/path/id/',
  11. 'path_big_foto' => 'dir/user/big_foto/path/id/',
  12. 'path_mini_foto' => 'dir/user/mini_foto/path/id/',
  13. ]
  14. ];
  15.  


użycie klasy

  1. <?php
  2. namespace Controllers;
  3.  
  4. use Helpers\Url;
  5. use Core\Config;
  6.  
  7. public function mojeKonto()
  8. {
  9. ...
  10. $this->cfg = new \Core\Config();
  11.  
  12. $this->cfg->get('ogloszenia.img.path_thumbs');
  13. $this->cfg->get('ogloszenia.base_url_img');
  14. }


nowa klasa

  1. <?php
  2.  
  3. namespace Core;
  4.  
  5. class Config {
  6.  
  7. public $config = array();
  8. private $configs = array();
  9. private $filePath = 'app/config/';
  10.  
  11. public function __construct() {
  12.  
  13. }
  14.  
  15. public function get($var) {
  16. if (isset($this->config[$var])) {
  17. return $this->config[$var];
  18. } else {
  19. $this->getValue($var);
  20. return $this->config[$var];
  21. }
  22. }
  23.  
  24. private function getValue($var) {
  25. $list = explode('.', $var);
  26. $key = end($list);
  27. $array = $this->getFile($list);
  28.  
  29. if (isset($array[$key])) {
  30. $this->config[$var] = $array[$key];
  31. } else {
  32. foreach ($array as $segment) {
  33. if (isset($segment[$key])) {
  34. $this->config[$var] = $segment[$key];
  35. }
  36. }
  37. }
  38. }
  39.  
  40. private function getFile($list) {
  41. if (!isset($this->configs[$list[0]])) {
  42. $configFile = $this->filePath . $list[0] . '.php';
  43. if (file_exists($configFile)) {
  44. $this->configs[$list[0]] = require_once($configFile);
  45. } else {
  46. throw new Exception('Cannot read the configuration file: ' . $configFile);
  47. }
  48. }
  49. return $this->configs[$list[0]];
  50. }
  51.  
  52. }
  53.  
  54.  
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.