2012-03-07 13 views
7

Potrzebuję móc edytować pliki .ini (które czytam z plikiem parse_ini_file), ale w ten sposób, że zachowywane są komentarze i formatowanie (podział linii, wcięcia).Dobre klasy PHP, które manipulują plikami .ini

Czy znasz jakieś dobre klasy, które mają ładne i zoptymalizowane funkcje dla tego rodzaju rzeczy?

+1

Czy masz próbki wejścia i wyjścia? –

+0

Wygląda jak standardowy plik ini, taki jak php.ini, 4-5 sekcji z pewnymi wpisami key = value wewnątrz nich – Alex

+0

Wątpliwość coś podobnego istnieje w międzyczasie (dla PHP). Miałem [editconfigini.php'] (http://apt.include-once.org/php/), ale to ignoruje sekcje i dba tylko o ograniczony format key = value. – mario

Odpowiedz

4

można spróbować począwszy od tego, odczytuje plik ini i zachowuje ustawienia dotyczące zapisu, trzeba by przedłużyć go wspierać dodając nowe pozycje:

class ini { 
    protected $lines; 

    public function read($file) { 
     $this->lines = array(); 

     $section = ''; 

     foreach(file($file) as $line) { 
      // comment or whitespace 
      if(preg_match('/^\s*(;.*)?$/', $line)) { 
       $this->lines[] = array('type' => 'comment', 'data' => $line); 
      // section 
      } elseif(preg_match('/\[(.*)\]/', $line, $match)) { 
       $section = $match[1]; 
       $this->lines[] = array('type' => 'section', 'data' => $line, 'section' => $section); 
      // entry 
      } elseif(preg_match('/^\s*(.*?)\s*=\s*(.*?)\s*$/', $line, $match)) { 
       $this->lines[] = array('type' => 'entry', 'data' => $line, 'section' => $section, 'key' => $match[1], 'value' => $match[2]); 
      } 
     } 
    } 

    public function get($section, $key) { 
     foreach($this->lines as $line) { 
      if($line['type'] != 'entry') continue; 
      if($line['section'] != $section) continue; 
      if($line['key'] != $key) continue; 
      return $line['value']; 
     } 

     throw new Exception('Missing Section or Key'); 
    } 

    public function set($section, $key, $value) { 
     foreach($this->lines as &$line) { 
      if($line['type'] != 'entry') continue; 
      if($line['section'] != $section) continue; 
      if($line['key'] != $key) continue; 
      $line['value'] = $value; 
      $line['data'] = $key . " = " . $value . "\r\n"; 
      return; 
     } 

     throw new Exception('Missing Section or Key'); 
    } 

    public function write($file) { 
     $fp = fopen($file, 'w'); 

     foreach($this->lines as $line) { 
      fwrite($fp, $line['data']); 
     } 

     fclose($fp); 
    } 
} 

$ini = new ini(); 
$ini->read("C:\\php.ini"); 
$ini->set('PHP', 'engine', 'Off'); 
echo $ini->get('PHP', 'engine'); 
$ini->write("C:\\php.ini"); 
+0

dziękuję. czy wiesz, jak zrobić komentarz/białą spację, wyreżyserować również nowe linie (jak puste nowe linie)? – Alex

+0

ps: Używam twojego regex do "nagrania" tylko dodatkowe dane, takie jak komentarze, które następnie przechodzę do konfiguracji generowanej przez klasę zend config, która jest taka fajna :) – Alex

+0

@Alex: Zapomniałem znaku zapytania w moim komentarzu regex, który powinien uczynić "dwukropek za czymkolwiek" opcjonalnie. Jak to działa? – Martin

5

nie używałeś config writer w ramach komponentu Zend, ale Użyłem czytelnika config, i był bardzo niezawodny. Na pewno warto było iść.

+0

Wypróbowałem to i jest naprawdę fajne, ale pisarz nie zachowa komentarzy, to po prostu wygeneruje nową strukturę ini :( – Alex

+0

Jeśli to jedyny problem, może zhakujesz tę funkcję? Oczywiście byłoby świetnie, gdyby takie zmiana może powrócić do wersji open source - jeśli tylko możesz skorzystać z ich aktualizacji - ale myślę, że to zależy od polityki Zend dotyczącej stabilności funkcji/api – halfer

+0

Lub możesz podklasować klasę pisarzy Zend z twoją własną klasą, zawierającą komentarze komentujące – halfer

2

Pakiet PEAR::Config posiada wsparcie dla komentarzy , więc zakładam, że je zachowuje. Prawdopodobnie pasuje do twoich potrzeb.