Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Budowa aplikacji MVC i plik konfiguracyjny.
Forum PHP.pl > Forum > Przedszkole
pijanyadmin
W jaki sposób odczytujecie plik konfiguracyjny w swoich aplikacjach?

Załóżmy że w wielu klasach odczytywana jest tablica z pliku np.

  1. $config = Config::read('plik.php');


  1. class Config
  2. {
  3. private static $opt;
  4. private static $file;
  5.  
  6. private function __construct(){}
  7. private function __clone(){}
  8.  
  9.  
  10. /**
  11.   * Odczytuje parametry pliku konfiguracyjnego
  12.   *
  13.   */
  14. public static function read($var=null)
  15. {
  16. if(!isset($var) OR empty($var) OR !is_string($var))
  17. {
  18. return null;
  19. }
  20.  
  21. static::getAll(self::$file);
  22.  
  23. if(isset(self::$opt[$var]))
  24. {
  25. return self::$opt[$var];
  26. }
  27.  
  28. if(false !== strpos($var, '.'))
  29. {
  30. $names = explode('.', $var, 3);
  31. //pr($names);
  32. $var = $names[0];
  33. //pr($var);
  34. switch (count($names))
  35. {
  36. case 2:
  37. if(isset(self::$opt[$var][$names[1]]))
  38. {
  39. return (string)self::$opt[$var][$names[1]];
  40. }
  41. break;
  42. case 3:
  43. if(isset(self::$opt[$var][$names[1]][$names[2]]))
  44. {
  45. return self::$opt[$var][$names[1]][$names[2]];
  46. }
  47. break;
  48. }// end switch
  49.  
  50. }// end strops
  51.  
  52. return null;
  53. }// end function read
  54.  
  55.  
  56. /**
  57.   * Ładuje plik konfiguracyjny
  58.   *
  59.   */
  60. public static function load($var)
  61. {
  62. self::$file = basename($var);
  63. }// end function load
  64.  
  65.  
  66. /**
  67.   * Zwraca całą tablicę pliku konfiguracyjnego
  68.   *
  69.   */
  70. public static function getAll($file)
  71. {
  72. self::$file = basename($file);
  73.  
  74. if(file_exists(self::$file))
  75. {
  76. include self::$file;
  77. }
  78. else
  79. {
  80. return null;
  81. }
  82.  
  83. if(isset($config) AND is_array($config))
  84. {
  85. self::$opt = $config;
  86. unset($config);
  87. return self::$opt;
  88. }
  89. else
  90. {
  91. unset($config);
  92. return null;
  93. }
  94. }// end function getAll
  95.  
  96. } // end class Config


Jednak za każym razem gdy wywołam

  1. $config = Config::read('plik.php');


Plik jest wczytywany od nowa. Nie mogę użyć include_once ponieważ wtedy będzie odczytany tylko 1 plik konfiguracyjny i to zablokuje odczyt drugiego.
Sephirus
Zawsze możesz zrobić to na zasadzie takiej leniwej fabryki. Już mówię o co chodzi:

Załóżmy że w wielu miejscach używasz
  1. $config = Config::read('plik.php');


Odczytywanie pliku "plik.php" za każdym razem to strata wydajności itd itp...

Co zrobić? Jeżeli nie zapisujesz konfiguracji z poziomu PHP (choć to też w sumie nie stanowiło by problemu) najlepiej zrobić to tak:

1. dodaj do klasy config tablicę (private) o kluczach będących nazwami plików.
2. przy każdym wywołaniu sprawdzaj czy istnieje tablica z indeksem takim jak plik z argumentu metody ::read(...)
3. jeśli taki rekord istnieje w tablicy - zwracasz go
4. jeśli nie - metoda robi swoje, ładuje plik, zapisuje go do tablicy z indeksem równym nazwie pliku i zwraca
5. każde kolejne wywołanie idzie wtedy z tablicy (bez ponownego ładowania pliku)

smile.gif
pijanyadmin
W FW np CI mój kontroler musi dziedziczyć po kontrolerze CI. Czy jest sens takiego rozwiązania, że Główny kontroler wczytuje cfg jako
  1. $this->config = Config::read('plik.php');


A później w innym kontrolerze dziedziczę po nim ten kod przez extends i mogę w swojej klasię odczytać $this->config ? Czy to na jedno wyjdzie?
Sephirus
Jeżeli dobrze Cię zrozumiałem to samo dziedziczenie kodu wykona tą funkcję znowu więc będzie miał tak naprawdę 2 razy dobieranie się do tego pliku "plik.php" najpierw FC potem zwykły C :/
pijanyadmin
Sephirus - A co rozumiesz przez "Jeżeli nie zapisujesz konfiguracji z poziomu PHP" ?
Sephirus
W tych przykładach odczytujesz konfigurację z pliku php - ale czy planujesz na przykład ją z poziomu PHP zapisywać czyli na przykład:

  1. $config = Config::read('plik.php');
  2. $config->databaseUser = 'stefan';
  3. Config::save('plik.php',$config);


smile.gif
pijanyadmin
W zasadzie to mam z tym problem nadal...

  1. class Config
  2. {
  3. private static $opt;
  4. private static $file;
  5.  
  6. private static $configs = array();
  7.  
  8. private function __construct(){}
  9. private function __clone(){}
  10.  
  11.  
  12. /**
  13.   * Zwraca całą tablicę pliku konfiguracyjnego
  14.   *
  15.   */
  16. public static function get($file)
  17. {
  18. self::$file = basename($file);
  19.  
  20. if(isset(self::$configs[self::$file]))
  21. {
  22. echo '<div style=color:green>tablica</div>';
  23. return self::$configs[self::$file];
  24. }
  25. else
  26. {
  27. echo '<div style=color:red>include</div>';
  28. if(file_exists(self::$file))
  29. {
  30. include self::$file;
  31. }
  32. else
  33. {
  34. return null;
  35. }
  36.  
  37. if(isset($config) AND is_array($config))
  38. {
  39. self::$opt = $config;
  40. unset($config);
  41.  
  42. self::$configs = array(self::$file => self::$opt);
  43.  
  44. return self::get(self::$file);
  45. }
  46. else
  47. {
  48. unset($config);
  49. return null;
  50. }
  51. }
  52. }// end function getAll
  53.  
  54. } // end class Config


Nie wiem w którym miejscu robię błąd, ale nadal są includowane pliki...


Kod
Config::get('test2.ini.php');
Config::get('test.ini.php');
Config::get('test2.ini.php');


Powinno wczytać plik test2.ini.php i test.ini.php.
by_ikar
Nie wiem jaki to ma związek z mvc, no ale dobra niech będzie że ma.

Na swoje potrzeby, zresztą nie tylko ja tak robię, mam klasę która przechowuje konfigurację i nic więcej nie robi (nie pobiera żadnych plików, ani ich nie nadpisuje). Gdzieś na początku wrzucam tablicę konfiguracji do klasy:

  1. Config::add($this->loadConfig('config/settings.yml'));


i dostęp w obrębie całej aplikacji mam taki sam. Nie muszę wczytywać żadnych plików itp. A cała klasa konfiguracji to zwykłe setery i getery plus jedna prywatna właściwość, która przechowuje konfigurację i na której operują setery/getery. Czyli u ciebie metody: read, load moim zdaniem są zbędne. No chyba że masz różne pliki konfiguracyjne, ale to i tak powinieneś robić to inaczej.

EDIT: chyba zajarzyłem o co ci chodzi. Zrób sobie tymczasowo wszystkie właściwości publiczne i zaraz po wywołaniu:

  1. Config::get('test2.ini.php');


sprawdź sobie co trzymasz w tych właściwościach:

  1. var_dump(Config::$opt, Config::$file, Config::$configs);


I powoli całość rozkładaj na czynniki pierwsze. Tak samo powinieneś zresztą zrobić z ładowaniem konfiguracji:

  1. var_dump(Config::get('test2.ini.php'));
pijanyadmin
by_ikar - ale właśnie co to jest $this->loadConfig('config/settings.yml') ? Przecież wczytujesz i tak ten plik. Więc jak się do niego odwołujesz? I tak mam wiele plików konfiguracyjnych.

edycja:

Tak, rozbiłem je i zawierają to co mają zawierać. Prócz tego że tablica jest tylko jedna. W powyższym kodzie nie zapisuje się 2 kluczy i nie wiem dlaczego.
skowron-line
  1. self::$configs[self::$file] = self::$opt;


EDIT:

Popatrz jak to tutaj jest zrobione
https://github.com/kohana/core/blob/3.2/mas...kohana/i18n.php
Sephirus
Ok wszystko jest ok i jasne - linijka 42:

  1. // masz:
  2. self::$configs = array(self::$file => self::$opt);
  3.  
  4. // powinno być
  5. self::$configs[self::$file] = self::$opt;


wink.gif

EDIT: ooo Sorry @up - dłuugo pisałem odpowiedź bo mi przeszkodzili - dubel nie celowy wink.gif
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-2025 Invision Power Services, Inc.