Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [OOP] Klasa do parsowania/edytowania plików INI
Forum PHP.pl > Forum > PHP > Object-oriented programming
Babcia@Stefa
Witam, napisałem klasę do parsowania/edytowania plików INI.

  1. <?php
  2. class SimpleINIElement
  3. {
  4. protected $DataArray, $Mode, $Content, $TempVar, $CurrentData;
  5.  
  6. public function __construct($_FILE='')
  7. {
  8. if(is_file($_FILE))
  9. {
  10. $this->Mode = 'Edit';
  11. $this->Content = file($_FILE);
  12. $this->ReadFromFile();
  13. } else
  14. $this->Mode = 'Create';
  15. }
  16.  
  17. protected function ReadFromFile()
  18. {
  19. foreach ($this->Content as $line_number => $line)
  20. {
  21. // category
  22. if(eregi('[([0-9a-zA-Z]{0,100})]', $line)) //check valid
  23. {
  24. // gets an array
  25. preg_match_all("|[(.*.)]|U", $line, $this->TempVar['section']['pattern'], PREG_PATTERN_ORDER);
  26. $this->TempVar['section']['line'] = $line_number; // set temporary
  27. $this->DataArray[$this->TempVar['section']['pattern'][1][0]] = array(); // creating new category
  28. $this->CurrentData['section'] = $this->TempVar['section']['pattern'][1][0]; // sets a current category for new variables
  29. } elseif(preg_match('#.*([A-z0-9]+).*=.*([A-z0-9]+)*#', $line, $data)) { // add new variables (comments and variables)
  30. $_value = explode('=', $data[0]);
  31. if(substr($_value[0], 0, 1) == ';')
  32. {
  33. $var_key = substr($_value[0], 1, strlen($_value[0]));
  34. $this->DataArray[$this->CurrentData['section']]['vars'][substr($var_key, 0, strlen($var_key)-1)] = array('type' => 'comment', 'value' => substr($_value[1], 1, strlen($_value[1])));
  35. } else {
  36. $var_key = $_value[0];
  37. $this->DataArray[$this->CurrentData['section']]['vars'][substr($var_key, 0, strlen($var_key)-1)] = array('type' => 'variable', 'value' => substr($_value[1], 1, strlen($_value[1])));
  38. }
  39. }
  40. }
  41. }
  42.  
  43. public function DocumentWrite($_STATUS='')
  44. {
  45. if($_STATUS == 'XML')
  46. return $this->WriteToXML();
  47. elseif($_STATUS == 'INI')
  48. return $this->WriteToINI();
  49. else
  50. return $this->DataArray;
  51.  
  52. }
  53.  
  54. public function ThrowSection($_NAME='', $_COMMENT='')
  55. {
  56. if(!is_array($this->DataArray[$_NAME]) AND $_NAME)
  57. {
  58. if($_COMMENT)
  59. $_COMMENT = 'y';
  60. else
  61. $_COMMENT = 'n';
  62. $this->DataArray[$_NAME] = array('vars' => array(), 'blocked' => $_COMMENT);
  63. } else
  64. throw new Exception('SimpleINIElement::ThrowVariable error: Category already exists or is argument is
     empty.'
    );
  65.  
  66. }
  67.  
  68. public function ThrowVariable($_NAME='', $_VALUE='', $_CAT='', $_COMMENT='')
  69. {
  70. if(!$_NAME)
  71. throw new Exception('SimpleINIElement::ThrowVariable error: The first param. is empty, its a variable
     name!'
    );
  72.  
  73. if(!$_VALUE)
  74. throw new Exception('SimpleINIElement::ThrowVariable error: The 2nd param. is empty, its a variable v
    alue!'
    );
  75.  
  76. if(!$_CAT)
  77. throw new Exception('SimpleINIElement::ThrowVariable error: The 3rd param. is empty, its a variable c
    ategory!'
    );
  78.  
  79. if(!is_array($this->DataArray[$_CAT]))
  80. throw new Exception('SimpleINIElement::ThrowVariable error: Variable category does not exists.');
  81.  
  82. if($_COMMENT == '')
  83. $_temp_type = 'variable';
  84. else
  85. $_temp_type = 'comment';
  86.  
  87. $this->DataArray[$_CAT]['vars'][$_NAME] = array('value' => $_VALUE, 'type' => $_temp_type);
  88. }
  89.  
  90. protected function WriteToXML()
  91. {
  92. $xml = '<?xml version="1.0"?>';
  93. foreach ($this->DataArray as $key => $value)
  94. {
  95. $xml .= '<' .$key. '>';
  96.  
  97. if(count($value['vars']) > 0)
  98. {
  99. foreach ($value['vars'] as $kkey => $vvalue)
  100. {
  101. $xml .= '<variable name="' .$kkey. '" value="' .$vvalue['value']. '" type="' .$vvalue['type']. '"/>';
  102. }
  103. }
  104. $xml .= '</' .$key. '>';
  105. }
  106. return $xml;
  107. }
  108.  
  109. protected function WriteToINI()
  110. {
  111. $output = '';
  112. foreach ($this->DataArray as $key => $value)
  113. {
  114. $output .= "[".$key."]\n";
  115. if(count($value['vars'] > 0))
  116. {
  117. foreach ($value['vars'] as $kkey => $vvalue)
  118. {
  119. if($vvalue['type'] == 'comment')
  120. $output .= ';';
  121. $output .= $kkey." = ".$vvalue['value']."\n";
  122. }
  123. }
  124. echo '<br/>I: ' .$i. '<br/>';
  125. return $output;
  126. }
  127. }
  128. }
  129. $ini = new SimpleINIElement();
  130. $ini->ThrowSection('section1');
  131. $ini->ThrowSection('section2');
  132. $ini->ThrowSection('section3');
  133. $ini->ThrowSection('section4');
  134. $ini->ThrowVariable('TestVariable', 'Test variable value :)', 'section1', true);
  135. $ini->ThrowVariable('TestVariable', 'Test variable value :)', 'section2', true);
  136. print_r($ini->DocumentWrite('INI'));
  137. ?>


Problem tkwi w funkcji WriteToINI() gdyż zapisuje ona tylko jedną kategorię zmiennych, a funkcja WriteToXML() zwraca poprawny wynik w XML...

Nie wiem co jest przyczyną... może to mały błąd, literówka? smile.gif

Dziękuję, Babcia@Stefa
-=Peter=-
jest tak:

  1. <?php
  2. protected function WriteToINI()
  3. {
  4. $output = '';
  5. foreach ($this->DataArray as $key => $value)
  6. {
  7. $output .= "[".$key."]\n";
  8. if(count($value['vars'] > 0))
  9. {
  10. foreach ($value['vars'] as $kkey => $vvalue)
  11. {
  12. if($vvalue['type'] == 'comment')
  13. $output .= ';';
  14. $output .= $kkey." = ".$vvalue['value']."\n";
  15. }
  16. }
  17. echo '<br/>I: ' .$i. '<br/>';
  18. return $output;//przerywa pętle foreach
  19. }
  20. }
  21. ?>


a powinno być:

  1. <?php
  2. protected function WriteToINI()
  3. {
  4. $output = '';
  5. foreach ($this->DataArray as $key => $value)
  6. {
  7. $output .= "[".$key."]\n";
  8. if(count($value['vars'] > 0))
  9. {
  10. foreach ($value['vars'] as $kkey => $vvalue)
  11. {
  12. if($vvalue['type'] == 'comment')
  13. $output .= ';';
  14. $output .= $kkey." = ".$vvalue['value']."\n";
  15. }
  16. }
  17. echo '<br/>I: ' .$i. '<br/>';
  18. }
  19. return $output;
  20. }
  21. ?>


Pozatym po co odkrywasz drugi raz koło? Na co Ci metoda ReadFormFile? Przecież jest wbudowana funkcja parse_ini_file()...
Babcia@Stefa
Cytat(-=Peter=- @ 23.03.2008, 16:13:39 ) *
Pozatym po co odkrywasz drugi raz koło? Na co Ci metoda ReadFormFile? Przecież jest wbudowana funkcja parse_ini_file()...


1. To klasa która od zera czyta pliki INI i je przetwarza.

Cytat
Pozatym po co odkrywasz drugi raz koło?


questionmark.gif blinksmiley.gif

TO MÓJ 200 POST ! smile.gif


Dziękuję, Babcia@Stefa
-=Peter=-
Oj, chodzi mi o to że metoda ReadFromFile mogła by wyglądać tak:

  1. <?php
  2. public function ReadFromFile($fileName){
  3.  $this->DataArray = parse_ini_file($fileName, true);
  4. }
  5.  
  6. //lub
  7. public function ReadFromFile($fileName){
  8.  $this->DataArray = parse_ini_file($fileName);
  9. }
  10.  
  11. //lub jakis warunek (wyrażenia regularne), sprawdzające które wywołanie wykorzystać (takie coś jak masz w swojej metodzie)
  12. ?>
Babcia@Stefa
Heh, a to wykorzystywanie gotowej funkcji, ja chciałem mieć własną winksmiley.jpg

@edit
Do konfiguracji w formacie LUA jest jakaś wbudowana klasa? (jeśli nie to napiszę takową smile.gif)

Dziękuję, Babcia@Stefa
-=Peter=-
Hmm a dlaczego uparłeś się aby tej funkcji nie wykorzystać? Nie pojmuję tego... No chyba, że wolisz sobie utrudniać życie, jezdzić z Krakowa do Warszawy przez Gdańsk smile.gif

Pozatym ta Twoja funkcja jest dużo mniej wydajna od tej, którą ja podałem, bo wyrażenie regularne w pętli raczej nie jest zbyt ekonomiczne.
Babcia@Stefa
Tak.. ale przebudowa teraz klasy będzie bardzo kosztowna...

Dziękuję, Babcia@Stefa
wlamywacz
Cytat
Tak.. ale przebudowa teraz klasy będzie bardzo kosztowna...


Wlasnie w OOP chodzi o to aby tak nie bylo...

P.S. Nie mam polskich znakow
Sedziwoj
Cytat(wlamywacz @ 23.03.2008, 20:16:40 ) *
Wlasnie w OOP chodzi o to aby tak nie bylo...


Dokładnie, więc jak mówisz że taka zamiana wymagają dużo zmian, znaczy że masz źle napisane. Bo wymagana jest hermetyzacja, wtedy pewne fragmenty podmieniasz, ale nic oprócz tego nie musisz robić, całość już powinna z tego korzystać nieświadoma zmian.
likemandrake
Wiemy wszyscy, że OOP jest zwykle wolniejsze od programowania strukturalnego, czemu więc nie użyjesz funkcji parse_ini_file (o której mowa powyżej) dla przyspieszenia wydajności, tylko "uparcie" spowalniasz swój skrypt?
Sedziwoj
Cytat(likemandrake @ 24.03.2008, 15:16:13 ) *
Wiemy wszyscy, że OOP jest zwykle wolniejsze od programowania strukturalnego, czemu więc nie użyjesz funkcji parse_ini_file (o której mowa powyżej) dla przyspieszenia wydajności, tylko "uparcie" spowalniasz swój skrypt?


Użycie parse_ini_file() lub nie jest niezależne od stylu programowania, bo równie dobrze implementacje można napisać strukturalnie. Ogólnie nie ma sensu pisać coś co już jest napisane i to lepiej.
wlamywacz
Wiesz to minimalne zwolnienie nadrabia sie przejrzystoscią i latwoscia w modyfikowaniu
Cysiaczek
Hm? Zwolnienie? No bez jaj, to są milionowe części sekundy, to nie spowalnia. Nie żyjemy w czasach procesorów 286. Będzie ta funkcja wywoływana 10000000000 razy dziennie? Śmiem wątpić. Sam kiedyś myślałem, że trzeba każdą rzeczy napisać tak, aby była maksymalnie szybka, ale to ślepa uliczka, bo nie ma nic za darmo i spada przejrzystość kodu.

Pozdrawiam.
wlamywacz
Cysiaczek moj post mial sie odniesc do wypowiedzi likemandrake smile.gif
likemandrake
Cytat(Sedziwoj)
Ogólnie nie ma sensu pisać coś co już jest napisane i to lepiej.


W PHP zwykle jest tak (nie zawsze), że jeśli coś jest zaimplementowane natywnie, czy to przez moduł do parsera PHP (a więc jest napisane dla języka PHP w innym języku niż PHP - C, C++, itp.) działa po prostu szybciej, więc pod tym względem nie ma sensu pisać własnych implementacji, po za tym, że kod działa wolniej, to jest bardziej obszerny. Taki głupi przykład: pisanie wyrażenia regularnego do sprawdzania, czy ciąg tekstowy zawiera tylko znaki alfabetu łacińskiego i puszczenie przez powiedzmy funkcję preg_match jest znacznie wolniejsze niż użycie funkcji ctype_alfanum, która robi to samo, lecz znacznie wydajniej. Z wyrażeniami regularnymi jest troche inna bajka, ale tu chciałem tylko pokazać jaki skok wydajności można uzyskać.

Cytat(wlamywacz)
Wiesz to minimalne zwolnienie nadrabia sie przejrzystoscią i latwoscia w modyfikowaniu


Zgadzam się z Tobą. Przede wszystkim kod staje się przenośny, co jest bardzo ważne w zastosowaniach biznesowych i nie tylko. To minimalne zwolnienie może mieć duży wpływ na wydajność w baaardzo rozbudowanej aplikacji, ale coś za coś.

@Cysiaczek

Bardziej chodziło mi o optymalizację jak największą jaką się da, lecz żeby nie przesadzać z czasem poświęconym na ten proceder. Mam tu na myśli wiedzę o danym problemie i jak sobie z nim poradzić, a nie potem spędzać dziesiątki godzin nad szukaniem problemu "Czemu to tak wolno działa?".

Podsumowując, potrzebne przede wszystkim doświadczenie, znajomość funkcjonalności i wydajności funkcji wbudowanych, wiedza na temat jakiegoś problemu, czy lepiej użyć funkcji A, czy funkcji B.

Ameryki nie odkryłem, chciałem troszkę (za bardzo) rozwinąć własną myśl nad moją poprzednią wypowiedzią.

Pozdrawiam
Sedziwoj
Cytat(likemandrake @ 26.03.2008, 12:08:23 ) *
W PHP zwykle jest tak (nie zawsze), że jeśli coś jest zaimplementowane natywnie, czy to przez moduł do parsera PHP (a więc jest napisane dla języka PHP w innym języku niż PHP - C, C++, itp.) działa po prostu szybciej, więc pod tym względem nie ma sensu pisać własnych implementacji, po za tym, że kod działa wolniej, to jest bardziej obszerny. Taki głupi przykład: pisanie wyrażenia regularnego do sprawdzania, czy ciąg tekstowy zawiera tylko znaki alfabetu łacińskiego i puszczenie przez powiedzmy funkcję preg_match jest znacznie wolniejsze niż użycie funkcji ctype_alfanum, która robi to samo, lecz znacznie wydajniej. Z wyrażeniami regularnymi jest troche inna bajka, ale tu chciałem tylko pokazać jaki skok wydajności można uzyskać.


Z preg_match() trzeba uważać, bo nie wiem czy wiesz, że rozbicie przez nią jest szybsze od expolode()... Ale jak napiszesz coś co ręcznie, znak po znaku, sprawdza... lepiej nie mówić. Wydajności nie ma, do tego napomknięta znajomość problemów, przy wyszukiwaniu wzorca są dobre algorytmy, ale ich implementacja nie należy do przyjemnych, więc użyjmy tego co jest. Mimo wszystko trzeba wiedzieć jak to działa, bo czasem lepiej jest pominąć i użyć czegoś do specyficznego przypadku... ale to już jest wyższa szkoła jazdy.

Ogólnie jak coś jest w bibliotece należy z tego korzystać. A naukę poświęcić na pisane czegoś innego (chyba że ktoś chce wchodzić w problemy algorytmiki itp. ale raczej wątpię, do tego nie ten język)
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.