Miért publikus?

 

Ha egyszer valaki előveszi a most készülő fórum motorom forráskódját, és belenéz a BBCode parser osztályba, akkor két publikus függvényt fog látni. Az egyik az, amit meg kell hívni, hogy egy formázott üzenetből HTML kód legyen, a másik fejkommentje pedig közli, hogy nem szabad meghívni. Miért nem privát akkor? Lássuk…

Most hirtelenjében kétféle módot tudok mondani, hogy egy parser-t hogyan lehet megírni. Van egy nulladik is, de azt gyorsan el is vetem: egyszerűen str_replace() függvénnyel csereberélni a tag-eket. Ezzel hatalmas probléma, hogy a paraméteres tag-eket nem lehet feldolgozni. Oké, akkor a feledik megoldás az, hogy preg_replace(‘/\[[color=([0-9a-fA-F]{3,6})\](.*?)\[/color\]/s’, ‘<span style=”color:#${1}”>${2}</span>’, $text). Szuper, mindent megold! Őőőő. Majdnem. Ugyanis nem minden tag értelmezett mindenhol. (Pl: két egymásba ágyazott [b] az baromság, és a [li] tag-et sem értelmezzük [ul] vagy [ol] tag-en kívül.) Persze lehet mondani, hogy hibás kódot is meg tudja enni valahogy, és ne legyen hülye a user, ne írjon ilyet, de ez nem a legszerencsésebb megoldás…

Akkor az első értelmes megoldás az állapotgép, mindenki kedvence. A parser talál egy [img] tag-et, és akkor tudja, hogy egész addig minden a kép URL-jéhez tartozik, amíg nem talál egy [/img]-t. Ez nekem annyira nem tetszett, persze ez szubjektív, hogy melyik tetszik és melyik nem két egyforma eredményt nyújtó kódból.

A másik járható út egy rekurzív feldolgozás. Tankörtársam szerint csak azért választottam ezt, mert meghallgattam a deklaratív programozás tárgyat. 😀
Szóval a megoldáshoz a WordPress shortcode API függvényeit kezdtem el átgyúrni, mivel ott már volt egy elég körültekintően összehegesztett 27 soros regex kifejezés, és a köré épülő logika. Itt pedig roppant trükkösen preg_replace_callback() fv-t használnak, ami a regex találatot tartalmazó tömböt átadva hívja meg a callback függvényt. Ez így majdnem jó is, csak nem tudja, hogy éppen merre jár az egymásba ágyazott tag-ekben, szóval kicsit felturbóztam, hogy egy tömbben megkapja a callback a jelenlegi hierarchiát. Ehhez – mivel szebb/jobb megoldást nem találtam – lambda függvényt adtam callback név helyett.

preg_replace_callback(
    "/$pattern/s",
    function($m) use ($parents) {
        return self::replaceSingleTag($m, $parents);
    },
    $text
);

Ez azt tudja, hogy a függvény lokális $parents változóját elérhetővé teszi a labda függvény belsejében is, és ott meghívja a két paraméterrel a privát statikus metódust. Nice, gj, wp.
A gond ott kezdődött, amikor az Eee-men próbáltam futtatni szabtech előadás alatt… Nem érte el a metódust. Oh, yeah, PHP 5.4-ben módosították, hogy az inline metódusok az őket tartalmazó kód scope-jában/névterében futnak, nekem pedig 5.3 van telepítve. Ok, leszarom, akkor 5.4 lesz a minimum rendszerigény, én meg frissítem itt is a PHP-t. Egész addig tartottam magam ehhez a tervhez, amíg itthon meg nem néztem, hogy tulajdonképpen azon a szerveren, ahol ennek futnia kell majd, mi van telepítve…

5.2

:rufuckingkiddingme: Ebben a verzióban még nincs lambda se! Sebaj, még mindig van preg_replace(“/$pattern/se“, ‘osztály::metódus($1,$2,…,$6,$parents);’, $text), és create_function()  is. Per se ettől még nem lesz jó a scope, és publikussá kell tenni a függvényt, és ha valaki elolvassa a vonatkozó dokumentációt, és ránéz a 7 paraméterre, akkor rájön, hogy ez annnnnnyira nem is jó ötlet, a create_function meg legalább annyira átlátható, mint a szoftlab 5 java sablon.

És ezt az utat bejárva jutott el a kód oda, hogy a fent vázolt szexi megoldást lecseréltem egy privát statikus stack-re az osztályban, és a callback függvény publikus, csak nem akar szóbaállni senkivel.

   
There's no response yet to this post. You can leave yours at the bottom of the page. Pinging is currently not allowed.
 

Leave a Reply

 

You must be logged in to post a comment.