Tarkastellessa tekemäni foorumin suoritusnopeuksia huomasin, että foorumin ulkoasujapohja toimii todella hitaasti. Toimintaperiaate on, että pohjan muuntaminen lopulliseen muotoon on yhdessä funktiossa, joka sisältää kaikki korvattavat kohdat.
Funktioiden korvaaminen oli aluksi ongelma, sillä se ei kannattanut esimerkiksi str_replace:lla, koska funktio suoritetaan joka kerta tarkistuksen yhteydessä. Sen jälkeen kokeilin käydä kaikki löytyneet kohdat läpi strpos-funktiolla ja sitten korvata kohta call_user_func-funktion palautusarvolla joka saadaan ob:n avulla. Tämäkin tapa on hidas. En ole vielä tutustunut muiden vastaavien pohjien toimintatapaan.
Pohjafunktion rakenne on seuraavanlainen.
$teksti = korvaa_funktiolla("{funktio}","korvaava_funktio"); .. $teksti = str_replace("{kohta}",$muuttuja); ..
Onko tähän nopeampaa tapaa, vai pitäisikö funktiota jaotella pienempiin osiin?
En ole nyt ihan varma tulinko ymmärtäneeksi oikein :/. Mutta mietin, miksi tätä funktiota ei voisi suorittaa vain silloin, kun sisältöä on muutettu? Tuloksen se voisi tallentaa vaikka johonkin randomiin tekstitiedostoon.
Tollasessa tapauksessa ei tosiaan kannata suorittaa PHP-skriptiä joka sivunlatauksella vaan mieluummin ajaa skripti pelkästään sillon, ku muutat jotain sivulla. Eli teet niin, että ajat sen sivun tulostavan skriptin komentoriviltä ja ohjaat tulosteen html-tiedostoon, joka on sitte haettavissa serveriltä.
Esitänpä kysymyksen eri tavalla. Miten tekisitte foorumin suorituksen, jos pohja olisi seuraavanlaista.
<?php $pohja["kategoria"]='<tr><td colspan="5" width="100%">{kategoria_nimi}<br />{kategoria_kuvaus}</td></tr><tr><td colspan="2" width="62%">'.$kieli["foorumi"].'</td><td width="6%">'.$kieli["aiheita"].'</td><td width="5%">'.$kieli["vastauksia"].'</td><td width="22%">'.$kieli["viimeisin_viesti"].'</td></tr>'; $pohja["foorumi"]='<tr><td width="5%"></td><td width="50%"><a href="?showforum={foorumi_id}">{foorumi_nimi}</a><br />{foorumi_kuvaus}{foorumi_toiminnot}</td><td width="6%">{foorumi_aiheita}</td><td width="5%">{foorumi_vastauksia}</td><td>'.$kieli["aika_etuliite"]. '[päiväys]{viimeisin_viesti_aika}[/päiväys]<br />'.$kieli["vastaaja_etuliite"]. '{foorumi_viimeisin_lähettäjä}</td></tr>';
Pohjan suoritus tapahtuu niin, että kun aiotaan näyttää kategoria, ensin haetaan tiedot, sitten tulostetaan ensin tuo kategoria-kohta oikeisiin arvoihin muutettuna, ja sen jälkeen foorumit foorumi-kohdan mukaan muokattuna lopulliseen muotoon. Kaikkia tietoja ei voida näyttää milloin vain, koska muuttujia asetetaan suorituksen aikana.
.. (käydään läpi kategoriat, haetaan tiedot) echo muuta($pohja["kategoria"]); .. (katsotaan onko kategoriassa foorumeita, läpikäydään jokainen) echo muuta($pohja["foorumi"]); ..
Toivottavasti saitte selityksestä jotain selvää.
Tietysti, jos on nopeampi tai muuten parempi tapa tehdä pohja, niin ehdoittakaa ihmeessä.
No jos se on pakko noin vaikeasti tehdä niin eval saattaisi olla nopeampi kuin useampi str_replace. Vaikeampi mennä sanomaan enempää kun ei tiedä mitä kaikkea tuo muuta-funktio pitää sisällään.
Itsekin joskus kasailin jotain vastaavaa systeemiä, mutta hylkäsin koko roskan kun siitä ei loppujen lopuksi ollut mitään käytännön hyötyä.
Ja mitähän tapahtuu jos joku kirjoittaa viestiin {foorumi_toiminnot} tms.?
En tiedä mutta voisi olla nopeampaa käyttää smartyä tai kokonaan php pohjaista ite tehtyä josta käydään tietyt funktiot läpi.
Hassuahan tuontapaisissa templaateissa on se, että PHP on jo itsessään muuta haluttua tietoa ulos puskeva kieli. Tuollaiset ulkoasukoodikikkailut ja Smartyt lisäävät vain yhden samantapaisen layerin, joka onnistuisi PHP:lla ihan suoraankin. Alla esimerkki.
<html> <head> <title><?php echo $otsikko ?></title> </head> <body> <div id="dokumentti"> <h1 id="otsikko"><?php echo $otsikko ?></h1> <table id="foorumi"> <tr> <th><?php echo $kieli['huoneet'] ?></th> <th><?php echo $kieli['keskustelut'] ?></th> <th><?php echo $kieli['viestit'] ?></th> <th><?php echo $kieli['uusin_viesti'] ?></th> </tr> <?php /* huoneluuppi alkaa */ for($i = 0, $maxi = count($huoneet); $i < $maxi; $i++) { ?> <tr> <!-- ja niin edelleen --> </tr> <?php } /* huoneluuppi päättyy */ ?> </table> </div> </body> </html>
Eikö olekin siistiä? Tälläisen sivun voisi tehdä vaikka erilliseksi templaattitiedostoksi, joka lisätään sen jälkeen kun kaikki data on toisessa skriptissä alustettu valmiiksi ulostulostusta varten. Ainoa ero Smartyyn on se, että tulee hieman pidempi koodinpätkä jokaista arvoa kohden - mutta toisaalta toimii myös varmasti Smartyä tai mitään templaattijärjestelmää nopeammin.
Smarty kääntää koodit phpksi ja cachettaa ne. Ite olen tosin käyttänyt melkein pelkkää phptä. Googlella varmaan löytäis vertailuja
Smarty on lähinnä hyödyllinen jos tarvitsee saada PHP:sta/ohjelmoinnista mitään tajuamaton olemaan rikkomatta koodia, ts. se on hyödyllinen isommissa monen hengen projekteissa. Yksin tai parin hengen käytössä en näe sille kovinkaan suurta arvoa.
Tässä myös jonkun mielipidettä Smartystä:
http://lists.motion-twin.com/pipermail/phptal/2005-July/000426.html
Ja lisää Smartyn nopeudesta löytynee tämän kautta:
http://devzone.zend.com/node/view/id/943
Aihe on jo aika vanha, joten et voi enää vastata siihen.