ugrás a tartalomhoz

Konfigurációs fájlok paramétereinek szerkesztése PHP-val.

mapdesign18 · 2011. Dec. 31. (Szo), 17.43
Sziasztok!

A helyzetem az alábbi:
- van egy konfigurációs template fájlom, ami tartalmazza az alap konfigurációt és azokat a tokeneket amit replace-vel felcserélhetek.
- van egy elkészített fájlom, ahol már a replace és az értékek bevitele megtörtént.

A probléma:
- Az elkészített output fájl értékeit (a tokeneket) utólag is tudnom kellene módosítanom / írnom / olvasnom aminek nagy hátulütője: tartalmát az user átírhatja szóval változhat, akár egészében is.. csak a paraméterek maradnak.. felcserélődhet a sorrend, esetleg más karakterkódolás, stb...

Vegyük például egy SHOUTcast rádiószerver szimpla konfigurációs állományát:
- template fájl:
;DNAS configuration file

password={token:password}
adminpassword={token:adminpassword}
portbase={token:portbase}
requirestreamconfigs={token:requirestreamconfigs}
yp2={token:yp2}
log={token:log}
screenlog={token:screenlog}
maxuser={token:maxuser}

 [ ... és így tovább ... ]

- kimeneti fájl (kicsit felkavartam):
;DNAS configuration file

password=topsecret
w3cenable=1
w3clog=sc_w3c.log
publicserver=default
savebanlistonexit=1
adminpassword=topsecret
portbase=8000
requirestreamconfigs=1
yp2=1
banfile=sc_serv.ban
ripfile=sc_serv.rip
riponly=0
log=1
maxuser=32

 [ ... és így tovább ... ]

.. noh ebből kellene valami jót varázsolni.

Az eddigi kezdetleges megoldás:
- template fájl » output fájl: Egyszerű str_replace segítségével végigmászok a sorokon és kicserélem a tokeneket (itt kevés a hibázási lehetőség, mivel fix template-ről van szó szóval no problemo).
- ... az output fájl értékeinek beolvasásánál / módosításánál már viszont rendesen elakadok :-(.

"Hogyan csinálnám?"

- Indexelném az egészet egy adatbázisba, h ne kelljen mindig parse-olnom a fájlt.
- Aztán valahogy összehasonlítanám az adatokat és ami legjobban illik rá, azt a sort cserélném fel.

Célom

- A fájl műveletek ne legyenek megterhelőek, lehetőleg a legkevesebb erőforrást eméssze fel az elemzés és felcserélés (db index, stb..).
- Jól tudjon alkalmazkodni az output fájl változásaihoz.
- A kommenteket (//, ;, #) tudja figyelmen kívül hagyni.

Hmm.. belegondolva egyszerűnek tűnik, de agytörős. :-D Próbálom megoldani a dolgot, de örülnék, ha valaki tudna segíteni vagy egy olyan megoldást vagy utat mutatni amin jól elindulhatok :-).

Köszönöm!
 
1

parse_ini_file esetleg preg_match

szabo.b.gabor · 2011. Dec. 31. (Szo), 22.31
http://php.net/manual/en/function.parse-ini-file.php

http://hu.php.net/manual/en/function.preg-match.php

ezeket nézegesd szerintem
2

Köszi a tippet, ezeken már

mapdesign18 · 2012. Jan. 1. (V), 03.26
Köszi a tippet, ezeken már javarészt túl vagyok. Sajnos a parse_ini_file-nél "komolyabb" dolog kell, mert az konkrét formátumot szab meg és sajnos nem feltétlen ini szabványú fájlok lehetnek. Viszont a preg_match -et nemrég kezdtem el tesztelgetni ami jónak tűnik, igaz előbb is eszembe volt meg persze majd a regex-eket kell megfelelően kialakíti. Egyébként néztem a társát a preg_match_all-t, ami erőforrás szempontból lehet jobb (nem tudom), de testreszabásilag gázabb is, mint ha soronként preg_match-elnék.

Most úgy néz ki a cucc, hogy adatbázisba soronként felveszek minden értéket és "key"-t, majd a token-t replacelem.

Valahogy így:
|-------|----------------|-------|
| id    | key            | value |
|-------|----------------|-------|
| 1     | w3cenable=(.*) | 1     |
|-------|----------------|-------|


Ha ezt az úgymond index adatbázist használom, akkor talán megfogom tudni csinálni mindkét dolgot: kiolvasás és írás, mivel a key pont ezt a célt szolgálja.

Hmm... át gondolom még... de ha jutottam valamire megosztom, kóddal együtt :).

Addig is B.Ú.É.K mindenkinek!!!
3

egy megoldás...

bonga · 2012. Jan. 3. (K), 15.24
Én így kezdenék hozzá:
1. beolvasnám a fájlt egyben
2. explode() függvénnyel tömbbé alakítanám a fájl sorait
3. végigszaladnék az így kapott tömb elemein:
- ha üres a sor, akkor következő
- ha comment a sor, akkor következő
- ha kulcs=érték a sor, akkor explode() a sorra az elválasztónál és az így kapott tömb első eleme a kulcs, második eleme az érték, amit egy asszociatív tömbben, mint eredményt szépen lehet tárolni.

Valahogy így gondolom:

$config = array();

$sorok = explode("\r\n", file_get_contents(CONFIG_FILE));
foreach($sorok as $sor)
{
  if(trim($sor) == '') continue;
  if(substr($sor, 0, 1) == ';') continue;
  if(substr($sor, 0, 2) == '//') continue;
  $elemek = explode('=', $sor);
  $config[trim($elemek[0])] = trim($elemek[1]);
}
Innentől kezdve a $config tömbben megkapod az összes konfigurációs paramétert, lehet használni:

//Olvasás:
  echo($config['adminpassword']);

//Írás:
  $config['adminpassword'] = 'newtopsecret';
Ezt az asszociatív tömböt visszaírni sem nagy kunszt:

$ini = '';
foreach($config as $kulcs => $ertek)
  $ini .= $kulcs . '=' . $ertek . "\r\n";
file_put_contents(CONFIG_FILE, $ini);
Persze így a fájlban tárolt megjegyzéseket elveszted... Lehet, hogy ez a megoldás nem optimális a problémára, de ha az ini fájlok kezelése nem sebességkritikus terület, használható egynek...

.bonga
5

Pár apró hátulütő, ami .ini

kuka · 2012. Jan. 3. (K), 16.10
Pár apró hátulütő, ami .ini állományok esetében bezavarhat:
  • szekciók: [szekcionev]
  • más komment jel: # komment
  • más elválasztó jel: ize: bigyo
  • sorvégi komment: ize=bigyo # komment
  • szóköz a komment jel előtt (ezt nem tudom reprodukálni BBCode-ban)
  • elválasztó jel az értékben: ize=bigyo=felugyelo
  • ismételhető állítás:
    tiltva=/cgi-bin/
    tiltva=/kepek/
    tiltva=/szemelyes/

  • többsoros állítás:
    ize=hipp-hopp\
    bigyo\
    felugyelo

  • idézőjel: ize=" bigyo megovja a kornyezo szokozoket "

Pár apró hátulütő, ami más állományok esetében bezavarhat:
  • szekciók:
    <szekcionev>
    </szekcionev>

  • egymásba ágyazott szekciók:
    <izeszekcio>
      <bigyoszekcio>
      </bigyoszekcio>
    </izeszekcio>

  • többsoros komment:
    /* a
    komment
    folytatodik */

  • több érték: ize="hipp-hopp" "bigyo" "felugyelo"

Én nem tekinteném ennyire sima ügynek. Főleg, hogy én ragaszkodnék a kommentekhez.
6

Részemről csak a komment a fontos.

mapdesign18 · 2012. Jan. 3. (K), 19.22
Részemről is fontosak a kommentek, viszont mivel konkrétan nem ini fájl kell output-ként ezért nem ennyire kötött a dolog. A szekciók kezelésére nekem speciel nincs szükség.

Jóval egyszerűbb a dolog, lent leírom bővebben.
7

Tetszik a megoldás.

mapdesign18 · 2012. Jan. 3. (K), 19.24
Tetszik a megoldás, köszönöm. Igaz bennem is felmerült. Lent leírom, hogy mi a problémám ezzel.

Ui: A "\r\n" nem mindig jó, főleg linux alatt. Soronkénti olvasásos megoldás lehet jobban jönne. :)
4

Ha jól értem a problémádat

inf · 2012. Jan. 3. (K), 16.01
Ha jól értem a problémádat van egy ini fájl sablonod, amiből a megadott paraméterekkel rendes ini fájlt szeretnél csinálni?

kieg:
Kicsit átolvastam, szóval van egy sablon, ami alapján ini fájlok készülnek aztán ezeket az ini fájlokat újra parsolni akarod? Nem nagyon értem, hogy ezt így minek, miért nem mented el a paramétereket, amik alapján az ini fájlok készülnek? Egyébként sablonozásra (hacsak nem valami nagyon egyszerű dologról van szó) jobb valami létező sablonnyelvet használni, mint pl az XSL... Teljesen felesleges új nyelveket kitalálni, amikor már van egy rakat létező... Mondjuk akár php-ben is megírhatnád a sablont...
8

Nem egészen.

mapdesign18 · 2012. Jan. 3. (K), 19.28
Nem pontosan ini fájlról beszélek, lehet egyéb konfigurációs fájl is az, hogy most ez a forma hasonlít az ini-re véletlen egybeesés.

Egy olyan globális megoldást keresnék, ami minden esetben jól működik. Éppen ezért nem hagyatkozhatok pl.: az egyenlőségjelre meg semmi ilyesmire csak a token-ekre a template fájlban.

Szóval kicsit átfogalmazva a dolgokat:

Tételezzük fel, hogy van egy template fájlom. Ez tartalmaz egy alap konfigurációt és néhány helyzetben tokeneket amit felcserélek. Például:

template.config
seta valami_ertek_1 "FIX_parameter"
seta valami_ertek_2 345345345

seta valami_valtozo_ertek "{token:valami_valtozo_ertek_felcserelese}"
[.. és így tovább több soron át ..]


Van egy output fájlom, aminek a tartalma totál eltérhet.. egyenlőséget kell valahogy keresnem és a token helyét valahogy ismét felcserélni:

output.config
seta valami_ertek_1 "FIX_parameter"
seta valami_ertek_2 345345345

seta valami_ertek_2 345345345

seta valami_valtozo_ertek "Valami érték, amit megváltoztattak"
seta valami_ertek_4 "FIX_parameter"
seta valami_ertek_75 345345345


Vmi ilyesmire gondolok API szinten:

$cfg = new ConfigAPI;
$cfg->open('output.config');
$cfg->open_tpl('template.config');

$cfg->set_token('{token:valami_valtozo_ertek_felcserelese}', 'Valami érték, amit sikeresen megváltoztattam');

$cfg->save();
Az új output meg ilyen lenne:
output.config
seta valami_ertek_1 "FIX_parameter"
seta valami_ertek_2 345345345

seta valami_ertek_2 345345345

seta valami_valtozo_ertek "Valami érték, amit sikeresen megváltoztattam"
seta valami_ertek_4 "FIX_parameter"
seta valami_ertek_75 345345345


Sajnálom, hogy WL-en nem tudom színekkel jobban kimutatni a lényeges részeket, így a vastagítással és dőlttel próbáltam. De remélem érthető a dolog. :)
9

Nem lenne erre jobb egy XML?

inf · 2012. Jan. 3. (K), 19.57
Nem lenne erre jobb egy XML? Azt XSL-el olyanra konvertálod, amilyenre csak akarod...

Ahogy nézem mondjuk ez egy tűrhető leírás róla. Itt arról van szó, hogy az XSL kétféle paramétert kap, az egyik az XML fájl, amit feldolgoz, a másik meg a processor-nak adott paraméter.
Akár azt is meg tudod csinálni, hogy ha a processor-nak megadtad azt a bizonyos paramétert, akkor felülírja az XML-ben találhatót, és a kimeneti XML-ben már az szerepeljen, ha viszont nem adtad meg, akkor maradjon benne a régi...

Mondjuk én még mindig nem teljesen értem, hogy ez az egész mire jó, és miért fájlokkal kezeled... Normál esetben mondjuk kiteszel egy űrlapot, kitölti a felhasználó, lemented adatbázisban és kész. Utána ha módosítani akar, akkor visszatöltöd adatbázisból, és újra lemented az egészet. Ha meg fájlt akarsz generálni ez alapján, akkor kikeresed adatbázisból, és fájlt generálsz egy sablonnal belőle. Ennyi.
10

Ha jól értem egy segédeszközt

kuka · 2012. Jan. 3. (K), 20.02
Ha jól értem egy segédeszközt szeretnél amely az általad írt szoftver frissítésekor a korábbi verzió állításaiból átveszi azt amit a felhasználó korábban már megváltoztatott?