Alt om ingenting og litt i mellom En blogg av Knut-Olav

WordPress plugins – katalogstruktur

7. juni 2007 · Én kommentar

Når man utvikler en plugin for WordPress som stadig utvides med ny funksjonalitet kan den vokse så stor at det kan bli et uhåndterbart antall filer i pluginkatalogen eller at filene rett og slett blir så store at det er vanskelig å få oversikt over funksjonaliteten i filene. Dette går også ut over ytelsen til WordPress. Et eksempel er plugin-siden i administrasjonsgrensesnittet som søker i alle PHP-filer i alle underkataloger ett nivå under plugins-katalogen etter filer med en plugin-header.

Dersom man kun beholder én PHP-fil, som vi kaller for “loader”, i rotkatalogen til pluginen kan ytelsen økes noe. Denne filen inneholer plugin-headeren og den eneste oppgaven til denne filen er å laste de resterende filene i pluginen. Denne loaderen vil videre laste en kontroller i en katalog vi kan kalle for “core”. Denne kontrolleren har som oppgave å sette opp hooks for å intregere mot WordPress og ellers kontrollere dataflyten i pluginen.

Den viktigste grunnen for å organisere filene sine er for å få bedre oversikt. En måte å gjøre dette på er å benytte underkataloger basert på funksjonalitet og filtype. For eksempel kan man plassere alle Javascript-filer i en “js”-katalog og alle CSS-filer i en “css”-katalog. Dersom pluginen din skal ha et administrasjonsgrensesnitt kan disse filene legges i katalogen “admin”, og en widget-støttet plugin kan ha widget-relaterte filer i en “widget”-katalog. All denne strukturen krever litt ekstra koding og flere filer å holde styr på, men til gjengjeld slipper man å se sine filer vokse til store monstere på flere tusen linjer. Store filer kan lett bli et problem, noe jeg selv har erfart i utvikling av WordPress-plugins.

Eksempel på katalogstruktur for en plugin av passe stor størrelse:

my_plugin_loader.php
/actions/controller.php
/actions/widget.ajax.php
/admin/options.php
/core/my_plugin.php
/css/admin.options.css
/css/widget-css.php
/js/script-loader.php
/js/some_lib.js
/js/widget-js.php
/languages/my_plugin-nb_NO.po
/languages/my_plugin-nb_NO.mo
/widget/widget.control.php
/widget/widget.php

Jeg har her brukt noen passende filnavn. Det er ofte ikke nødvendig å spesifisere katalognavnet som en del av filnavnet, men av og til kan det være smart, avhengig av hvilken editor som benyttes. Selv benytter jeg Eclipse som viser kun filnavnet, og det kan være vanskelig å skille tre åpne filer som alle heter “control.php” fra hverandre.

Jeg har tatt med i eksempelet en fil som heter “script-loader.php” som kan benyttes for å laste Javascript-filene. WordPress har funksjonalitet for å registrere Javascriptene med navn, URL og avhengigheter. Det er også mulig å spesifisere versjon av Javascriptet, som blir en del av URL-adressen til filen. Dette er svært aktuelt for å tvinge nettlesere til å laste den nye Javascript-filen fremfor å benytte en som kan finnes i en cache ett eller annet sted.

Man kan ha behov for å kalle på funksjonalitet i pluginen som ikke skal benytte det vanlige themet til WordPress, men kanskje bare returnere noe data til et Javascript, utføre en oppdatering eller printe ut en CSS- eller Javascript-fil. Man kan dermed ha behov for en egen front-kontroller som tar seg av disse forespørslene.

Jeg benytter PHP5 og objektorientering for å utvikle plugins til WordPress, men tankene og forslagene i denne artikkelen kan like gjerne benyttes med en strukturell programmeringsmetodikk. Jeg synes det er alt for mange dårlig skrevne plugins for WordPress, hacket sammen for å gi funksjonaliteten som er ønsket på det gitte tidspunktet. Dette gjør det vanskeligere å vedlikeholde dem senere når nye krav kommer og det gjør integrasjon med andre plugins og nyere versjoner av WordPress til et mareritt. Disse pluginene benyttes så som et utgangspunkt for nye plugins ved hjelp av copy/paste-metoden. Jeg tror at bedre dokumentasjon med gode eksempler kan bidra til bedre kodestandard på plugins.

Første middag på verandaen

2. mai 2007 · Comments Off

Knut-Olav på verandaenEt historisk øyeblikk har kommet over meg. I dag tok jeg min første middag ute på verandaen min. Jeg har fått meg utemøbler, fire stoler og et bord. Etter hvert skaffer jeg meg også en grill, og jeg gleder meg til å nyte pils og hamburgere når sommervarmen steker for fult.

Første middag på verandaenJeg laget meg taco til middag, satte på Roger Waters konsert-DVD på passende lydstyrke og koste meg ute. Selv om jeg ikke har sola med meg etter ca kl 12 på dagen så var det godt og varmt utendørs i kveld. Jeg ser for meg flere dager ute på verandaen og sikler på tankene om å sitte der ute med laptopen på fanget og en kald pils i hånda tidlig en sommermorgen.

Konfigurere Linksys WRT54GL i et større nettverk

1. mai 2007 · Én kommentar

Jeg har en lidenskap for nettverk og konfigurering av nettverksutstyr og tjenester. Hjemme, både i leiligheten og i huset til foreldrene mine, har jeg nettverk som kunne passet bra for en middels til stor bedrift, med egne servere for DNS, DHCP, Web, Mail, skriver- og fildeling, databaser og sentralisert autentisering av trådløse brukere.

Jeg har nylig kjøpt meg en Linksys WRT54GL v1.1 trådløs ruter som skal plasseres i nabohuset til foreldrene mine. Der bor bestemor, og min søster har flyttet inn der og ville gjerne ha Internett.

Jeg har trukket CAT-6 Ethernett-kabel mellom husene for å kunne gi et stabilt nettverk opp til nabohuset. Dette medfører fare for jordingsfeil som kan svi av diverse datautstyr dersom ting går skikkelig galt. Derfor har jeg også kjøpt en APC UPS med overspenningsvern for både strøm og nettverk. Jeg så muligheten for å også sette opp trådløst nettverk der, som kan være kjekt når vi er på besøk hos bestemor, for eksempel i jula. Ja, jeg er Internett-avhengig.

Systeminformasjon om ruterenNoe av det første jeg gjorde med ruteren var å slenge inn OpenWRT WhiteRussian, som en et alternativt firmware til Linksys sine egne. Jeg syntes denne firmwaren var noe mangelfull og lurte veldig på om jeg skulle gå tilbake til Linksys sin. Jeg oppdaget DD-WRT som er basert på kjernen til OpenWRT. Denne har støtte for det meste jeg kunne tenke meg, så valget falt på denne, versjon 23 SP2.

Oppsett av IP-adresser og DHCPJeg ønsket et oppsett hvor ruteren skulle kunne sende IP-pakker fritt frem og tilbake mellom grensesnittene på ruteren, og ikke bare være en NAT-enhet. Jeg er ikke hjemme hos foreldrene mine så ofte, da jeg bor i Drammen, så jeg må ha mulighet for å fjernstyre disse maskinene dersom det skulle være nødvendig. Jeg endret DHCP-tjenesten på ruteren til å videresende DHCP-forespørsler til FreeBSD-ruteren som står i huset til foreldrene mine. FreeBSD-ruteren kjører en DHCP-tjeneste slik at jeg får et sentralt styringspunkt for IP-håndtering. Jeg har satt av et nytt 24-subnett i DHCP-serveren min, tildelt den nye ruteren i nabohuset.

Deaktivert SPI-brannmurDD-WRT har som standard en aktiv SPI-brannmur som filtrerer alle pakker fra WAN-nettverket som forsøker å få tilgang til maskiner på baksiden av ruteren. Denne brannmuren måtte jeg skru av for at svar på DHCP-forespørslene skulle komme tilbake til klientene. På min hoved-ruter i huset til foreldrene mine har jeg satt opp en statisk rute til det nye 24-subnettet som rutes til WAN-grensesnittet på Linksys-ruteren.

Det er viktig at Linksys-ruteren har en fast IP-adresse på det opprinnelige subnettet, for at den statiske rutingen skal være stabil over tid. Dette gjorde jeg ved å konfigurere DHCP-serveren til å gi Linksys-ruteren en statisk IP-adresse.

Brann på toget

16. april 2007 · Én kommentar

Hva er det som er verre enn unødvendige annonseringer på toget? Brann kan vel sies å være hakket verre.

I dag, da jeg tok Kongsberg-toget kl 18:19 på vei hjem fra Oslo til Drammen, oppstod det problemer med det bakre togsettet etter Asker. Jeg tror problemene var relatert til bremsene til den bakre vogna. Det nøkket hardt i vognene mens togføreren forsøkte å kjøre toget sakte frem og tilbake for å løse problemene, noe som spesielt vi som satt bakerst merket godt. Det var også gjentatte strømbrudd og stans. Heldigvis gikk det greit for seg gjennom tunnellen mellom Asker og Lier.

Det oppstod røykutvikling et par meter foran meg på høyre side kort tid etter vi kjørte fra Lier stasjon. Det ble mer og mer røyk som ikke luktet spesielt godt, og vi som satt bakerst flyttet oss derfor fremover i toget og konduktøren ble kontaktet. Toget holdt lav fart, men kom allikevel et lite stykke vekk fra stasjonen. Toget rygget så tilbake til stasjonen og vi fikk beskjed om å trekke ned til veien da vi kom tilbake til Lier stasjon. Da jeg kom ut av toget var det mye røyk som steg opp fra den bakre vogna.

Toget brenner (3)
Vi trakk over på den andre siden av plattformen i håp om å bli plukket opp av neste tog som skulle forbi. Slik skulle det ikke skje, for det neste toget kom i svært høy fart forbi plattformen og tutet. Grunnen til det kom godt til syne da det begynte å brenne under den bakre vognen ved de fremste hjulene. Det røyk også ut fra ventilene på toppen av vognen. Det brant lenge og brannen ble større og det ble store svarte merker oppover ytterveggene på vognen.

Toget brenner (4)
Politiet ankom og etterhvert kom også noen brannbiler. Selvfølgelig stilte også pressen opp. Selv tok jeg noen få bilder med mobiltelefonen min.

Slutten på turen endte med en overfylt buss på helt ulovlig vis fra Lier, innom Brakerøya og til slutt, for min del, Drammen hvor jeg skulle av.

Oppdatering kl 23:00:
Drammens Tidene skriver på sine nettsider om hendelsen. Det var olje som tok fyr og brant under den bakerste vognen. En togkonduktør ble sendt til legevakten etter å ha pustet inn røyken.

Xen på (K)Ubuntu Edgy (X11-input og justering av klokke)

6. april 2007 · Comments Off

Jeg oppgraderte KUbuntu fra Dapper til Edgy på laptopen min nylig. Hovedgrunnen til dette var for å sette opp virtualiseringsløsningen Xen. Jeg er klar over at Xen på Ubuntu Edgy er “ødelagt”, noe jeg fant ut da jeg forsøkte å kjøre Ubuntu Edgy sin Xen-kernel på serveren min for en stund tilbake. Problemet lå i at Dom0, altså verten, ga kernel-panic når jeg startet den tredje Xen-instansen på serveren. Løsningen på dette problemet var å kjøre Red Hat sin Xen-kernel, og dette har fungert utmerket. Jeg kjører nå seks Xen-instanser på denne serveren.

Per Buer, avdelingsleder i drift hos Linpro, skriver i sin blogg at Red Hat Xen-kernel kan kjøres nesten ut av boksen på Ubuntu Dapper og er å foretrekke dersom man har behov for å aksessere mer enn 4 GB ram på et 32 bits system.

Foreløpig har jeg ikke støtt på samme problemet på laptopen min som oppstod med Ubuntu Xen-kernel på serveren min, da jeg enda ikke har hatt behov for så mange samtidige Xen-instanser. Første forsøket på å starte laptopen min med Red Hat sin Xen-kernel feilet, så jeg har latt den saken ligge for nå.

Problemet jeg har støtt på med å bruke Ubuntu sin Xen-kernel på laptopen er at tastaturet periodevis lagger når jeg er i X11 og KDE. Det tar da lang tid fra jeg trykker en tast til den tegnet blir printet i terminalen og ofte blir tasten utført to ganger, noe som gjør det svært vanskelig å programmere og gjøre vedlikeholdsarbeid i terminalen. I ett tilfelle så låste tastaturet seg fullstendig i hele X11, ingen taster ga reaksjon. Det hjalp ikke å bytte til et konsoll og så tilbake til X11, men det hjalp å restarte X11. Det var heller ikke mulig å holde en tast nede for å få repetert handlingen, for eksempel å holde ‘a’-tasten nede for å få skrevet ut dette tegnet gjentatte ganger. Problemet gjelder også for musen, for eksempel markering av tekst.

Dette problemet oppstår kun i Konsole og ikke i XTerm, som er de to terminalapplikasjonene jeg har forsøkt. Problemet oppstår også i andre programmer, som for eksempel Firefox. Jeg har kun forsøkt å bruke det innebygde tastaturet og musen på laptopen, ingen eksterne enheter. Laptopen er av typen IBM/Lenovo X60.

Som denne bug-rapporten viser så skal det være et problem i X11 på Dom0 med Ubuntu Xen-kernel dersom klokken stilles med for eksempel OpenNTPd. Da jeg skrudde av denne tjenesten forsvant problemet og jeg kan nå holde en tast nede for repeterende handling. Jeg klarer å gjenprodusere feilen ved å stille klokken med kommandoen:
ntpdate -u ntp.uio.no

Ved å skru av OpenNTPd så øker risikoen ved at klokken stilles feil over tid. Det er derfor viktig å passe på at klokken går riktig for å sikre riktig tid på for eksempel loggene og spesielt dersom det benyttes en sentral autentiseringsløsning som Kerberos. En mulig løsning er å synkronisere ved oppstart av maskinen. Dette vil ikke fungere med min løsning da jeg ofte er tilkoblet trådløst nettverk, som først konfigureres med KNetworkManager når jeg logger inn i KDE.

Ting som irriterer meg – annonseringer på toget

21. mars 2007 · Én kommentar

I dag derimot ble jeg en smule irritert. Det er ikke mye som skal til for at jeg blir litt irritert over dumme ting som skjer her i verden, men denne gangen så fikk jeg skrevet ned frustrasjonen min…

Jeg tar toget hver dag til og fra jobb. Det gir meg god tid til å tenke på alle mulige fornuftige og ufornuftige ting. Som for eksempel når jeg tar Kongsberg-toget fra Oslo til Drammen på kvelden, så hender det svært ofte at de stenger av de bakerste vognene når de kommer til Drammen. Greit nok for meg, siden jeg skal av i Drammen og gir blanke blaffen i hva andre passasjerer må gjøre, og greit nok for meg at de nevner det over høytalerne rett før toget kjører inn til plattformen.

Det som irriterte meg i dag var da togkonduktøren kom bak i toget mer enn 3 stasjoner i forveien for å fortelle at de som sitter her i det bakerste togsettet må flytte fram til det fremste fordi de skal stenge av det dette. Joda, herregud, fint nok det der med med informasjon og greier, men de som går av på en av de tre stasjonene før Drammen har da sikkert ikke så veldig mye lyst til å vite det. Det ble jo annonsert lenge før toget kom inn til Asker!

En annen ting er jo at en slik annonsering innebærer ufattelig mye usikkerhet blant kundene fordi det alltid er noen som sliter med å få med seg det som blir sagt og blir dermed sittende og lure på om de må bytte togsett allerede på neste stasjon eller ei. Spesielt vanskelig er det for de som ikke forstår norsk, de må jo da spørre en av de andre passasjerene om hva som ble sagt, og der oppstår det gjerne også litt misforståelser. For eksempel, om man skal bytte vogn allerede på neste stasjon? Hvilken stasjon er Drammen? Skal vi bytte tog? “Where the fuck is Drammen?” Nei, dere irriterte meg faktisk en god del i dag, NSB!

Vanligvis klarer dere det ganske lett. Dere trenger bare å ta bort et par vogner fra toget slik at jeg må stå trangt og svett og klemt inn i et hjørne nede ved døra og må gå ut på plattformen på hver eneste stasjon for å slippe fram folk, eller når dere blir forsinket fordi dere må vente på en ansatt som har forsovet seg, kommer med at annet forsinket tog og slike ting… Etter de mange årene jeg har kjørt tog så har jeg begynt å venne meg til slikt. Det begynner å bli standard prosedyre, rett og slett. Men å mase lenge før Asker om at jeg, og mange andre må flytte oss noen vogner framover når vi kommer til Drammen synes jeg er å ta litt hardt i. Halvparten av de i vogna gikk jo av i Asker, og nesten like mange kom på! Jeg forstår ikke poenget, dere må jo uansett gå bak i vognene når toget kommer til Drammen for å sjekke at ingen sitter igjen der!

Fikk liksom litt følelsen av Family Guy og “What really grinds my gears”… Vel, nå har jeg i det minste fått ut litt av min aggresjon om ting som irriterer meg. Dette er jo ikke første gangen, det vet mine faste lesere (jeg har minst 2!!), og det blir garantert ikke den siste gangen.

WordPress plugins – Front Controller

8. mars 2007 · 2 Kommentarer

WordPress støtter utvidelser via plugins. Plugins kommuniserer med WordPress-kjernen ved å hekte seg på kroker (hooks). Disse krokene blir eksekvert visse steder i koden, for eksempel når en side med poster skal vises, når en bruker opprettes eller når en post slettes.

Det er en handlingskrok (action hook) som heter “init” som blir kalt på rett før themet skal lastes inn for presentasjon av postene. Når denne kroken skal eksekveres er plugins lastet og innstillinger lest fra databasen, så denne kroken egner seg svært godt for det jeg nå skal vise, nemlig hvordan man kan kalle på funksjoner i sin egen plugin med via lenker på siden, med HTML forms eller via Javascript og AJAX.

Jeg har ofte hatt behov for å kalle på funksjoner i min plugin fra Javascript på siden, også kjent som Ajax/Web2.0. Jeg har utviklet en plugin som lar brukeren sette et filter, slik at kun innlegg som matcher dette filteret vil bli vist. Jeg skrev denne pluginen på jobben og den er foreløpig kun for internt bruk og er derfor ikke tilgjengelig, men det hindrer meg ikke i å forklare hvordan jeg har brukt denne teknikken.

Dette filteret settes i cookie i nettleseren til brukeren slik at filteret er aktivt helt til brukeren bytter til et annet filter. Filtere kan ligge i nivåer underhverandre. Tenk på det som kategoriene i WordPress, hvor kategorier kan ha en forelderkategori. Jeg skal her vise to eksempler hvor jeg først bruker en link for å bytte til et annet filter, for så å vise hvordan jeg bruker AJAX for å hente en liste med filter.

Linken for å bytte filter kan for eksempel se slik ut:

<a href="http://example.com/?myplugin=set&filter=sport">Sport</a>

Da har jeg behov for en sjekk i min plugin, som jeg har valgt å kalle “myplugin” (ja, jeg vet, men dette er ikke navnet på min ekte plugin ;) ), for å kunne snappe opp ønsket om å bytte filteret til “sport”. Jeg har valgt kodeordet “myplugin”, det samme som navnet på pluginen jeg har skrevet for å minke risikoen for navnekollisjon. Jeg har en funksjon jeg har hengt på “init”-kroken som sjekker om kodeordet er blitt angitt i adressen samt om det finnes en passende handling å utføre.

I eksempelet nedenfor viser jeg også PHP-kode som tar i mot ønsket om å liste ut alle filtere som har et angitt filter som forelder. Legg merke til dersom testen matcher ‘list’ vil den printe ut listen for så å dø, hardt og brutalt. Dette er faktisk ønskelig fordi vi skal utføre et asynkront kall med Javascript, noe som betyr at nettsiden ikke skal lastes på nytt, men bare en liten del av nettsiden skal oppdateres. Det som PHP-scriptet skriver ut i eksempelet nedenfor blir hentet opp av Javascriptet som utførte kallet, klar til å inkluderes på nettsiden. Om det er en <select>-liste, en rekke med checkboxer eller noe annet som gjøres med denne listen bestemmes av Javascriptet.


$myplugin = new MyPlugin();
add_action('init', array(&$myplugin, 'check_action'));
//
// Hovedklassen i min plugin
class MyPlugin {
    function check_action() {
        $action = _REQUEST['myplugin'];
        switch($action) {
            case 'set':
                $this->set_filter($_REQUEST['filter']);
                break;
            case 'list':
                $list = $this->get_list($_REQUEST['parent']);
                echo $list;
                exit;
        }
    }
    // Setter nytt filter
    function set_filter($filter = '') {
        // Setter en cookie for brukerens nettleser
    }
    // Returnerer en liste med filtere som har en angitt forelder
    function get_list($parent = '') {
        // finner og returnerer listen med angitt forelder
    }
}

Hvordan Javascriptet som utfører dette asynkrone kallet er programmert skal jeg ikke komme inn på her. Det er et for stort tema å skrive om i denne artikkelen, men det finnes gode ressurser på Internett om AJAX, Google vet det meste. Det kan være verdt å sjekke ut Cross-Browser XMLHttpRequest, som gjør det enklere å bruke Ajax uten at man vrir seg i smerte over de mange forskjellige teknikkene som er brukt i nettlesere.

Konvertere mellom store og små bokstaver i PHP med mb_convert_case / strtolower

7. mars 2007 · Comments Off

Jeg følger opp gårsdagens innlegg med et nytt PHP-tips, denne gangen for å konvertere mellom store og små bokstaver. Til dette kan funksjonen mb_convert_case benyttes.

Dersom man utvikler nettsider som skal ha støtte for flere språk er det vanskelig å komme utenom UTF-8, unicode. Ofte vil man teste på en variabel om den matcher et sett med konstanter eller andre variable som brukere skriver inn. Brukere er generelt sett svært ustabile når det gjelder hva input som kan komme inn til serveren, spesielt når det gjelder bruk av store og små bokstaver.

Et eksempel på dette er tagger i WordPress. Hvorfor skal man måtte ha to separate tagger som betyr det samme bare fordi den ene ble skrevet med stor forbokstav mens den andre med liten? Her kan det være kjekt å bruke PHP-funksjonen strtolower, helt til man kommer til spesielle bokstaver og tegn som ikke finnes i tegnsettet man normalt bruker, ofte ISO-8859-1 av en variant. Dette kan fungere greit dersom teksten som kommer inn er i samme tegnsett som serveren benytter, men når det gjelder unicode så er saken annerledes.

Strenger eier ingen informasjon om hvilket tegnsett som benyttes, dette må utviklere holde orden på. Funksjonen strtolower takler unicode svært dårlig. Spesielle tegn, som de norske bokstavene æøåÆØÅ, kodes i unicode med lengden av to vanlige bokstaver. Dette fører til at strtolower deler disse tegnene i to før den utfører konverteringen. Resultatet av dette blir mest sannsynlig et uventet tegn som nettleseren har problemet med å vise. Selv har jeg sett ?-tegnet ganske ofte ;)

Løsningen rundt dette problemet er å benytte PHP-funksjonen mb_convert_case. Som vist i eksempelet konverteres tekststrengen til små bokstaver, lowercase:


// UTF-8 tekststreng
$orig_string = 'Hei på deg. Hvordan er været i Østfold?';
$new_lower = mb_convert_case($orig_string, MB_CASE_LOWER, 'UTF-8');
echo $new_lower;

Funksjonen echo vil her skrive ut: hei på deg. hvordan er været i østfold?

Den første parameteren til mb_convert_case er tekststrengen som skal konverteres, mens den andre angir hvilken type konvertering som skal utføres, i form av en konstant. Følgende konstanter kan gis til mb_convert_case:

  • MB_CASE_LOWER: konvertere til små bokstaver
  • MB_CASE_UPPER: konvertere til store bokstaver
  • MB_CASE_TITLE: konvertere til stor forbokstav i hvert ord

Funksjonen mb_convert_case tar også en parameter som forteller hvilket tegnsett som ønskes brukt ved konvertering. På noen forum og mailinglister foreslås det at man kan bruke funksjonen setlocale før strtolower for å sette hvilket tegnsett som skal benyttes, men dette hjalp ikke i mitt tilfelle. Funksjonen mb_convert_case tar utgangspunkt i at tekststrengen er i unicode og klarer derfor å konvertere norske spesialtegn på en utmerket måte.

eAccelerator – en PHP-akselerator

7. mars 2007 · 2 Kommentarer

Jeg har utviklet en nettside, basert på WordPress, hvor vi hadde et problem med at den brukte alt for lang tid på å levere sidene til brukere, selv med bare 10-15 samtidige brukere. Problemet lå på Apache, som fikk serverloaden opp i omkring 7-8. Oppslag av hostnames i Apache var skrudd av og loggfilene var satt til å roteres hver dag for å forhindre alt for store filer. Siden PHP kjøres gjennom mod_php var dette neste stedet å undersøke. WordPress med et utallig antall plugins resulterer i svært mange PHP-filer som må lastes for hver eneste gang en nettside hentes. Selv et lite Javascript kan kreve mye ressurser dersom dette scriptet har behov for selv bare én enkelt variabel fra databasen. En caching-løsning som cacher HTML-sidene basert på URL og cookies, ala WP-Cache, var ikke noen god løsning, fordi sidene som vises for innloggede brukere ikke bare bestemmes av URL og cookies, men også av variabler hentet fra en database. Memcache ble benyttet for å cache variabler fra databasen for å minke antallet spørringer mot denne, men det hjalp ikke i lengden.

Løsningen på ytelsesproblemet kom med eAccelerator, en cache-løsning for PHP som cacher de kompilerte PHP-filene, slik at PHP ikke behøver å lese og kompilere alle PHP-filene for hver sidelasting. Andre nettbaserte løsninger som for eksempel benytter Java EE (Enterprise Edition) har en server som hele tiden kjører selv om ingen brukere besøker siden. Fordelen med dette er at alle filer med tilhørende klasser og andre ressurser allerede er lastet inn i minnet på serveren, noe som sparer diskaktivitet og prosessorkraft når brukere besøker siden din.

I dette prosjektet ble versjon 0.9.5 av eAccelerator benyttet. Uten å kjøre nøyaktige benchmarktester så virket denne løsningen betraktelig raskere; sidene lastet raskere i nettleserene og serverloaden er blitt gjennomsnittlig lavere.

eAccelerator finnes ikke i pakkesystemene til Ubuntu eller FreeBSD, så denne må manuelt lastes ned og kompileres. Man trenger dev-pakkene for PHP for å kompilere eAccelerator, da man trenger verktøyet phpize. Dev-pakken på Ubuntu heter php5-dev, eller php4-dev dersom denne versjonen benyttes.

phpize
./configure --enable-eaccelerator \
--with-php-config=/usr/bin/php-config
make && make install

Deretter må den aktuelle php.ini-filen som Apache benytter seg av for mod_php oppdateres med følgende innstillinger. Bemerk at kun første linjen er påkrevd. Standard katalog for cache-filene er /tmp/eaccelerator, så denne må opprettes og det må gis skriverettigheter til brukeren som Apache kjører som. På distribusjoner hvor /tmp katalogen slettes ved booting av operativsystemet bør cache_dir settes til en annen katalog, for eksempel /var/cache/eaccelerator. Verdiene i eksempelet nedenfor er hentet fra eAccelerator – Installing from source.

extension="eaccelerator.so"
eaccelerator.shm_size="16"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"

WordPress har et litt rufsete rykte, blant annet på grunn av at en WordPress-side ikke tåler trykket dersom en artikkel skrevet i en WordPress-blogg havner på forsiden av for eksempel Digg. Muligens kan en slik cache-løsning være redningen for WordPress, og forsåvidt andre PHP-applikasjoner.

Oppdatering 07.03.2007 08:38 CET
Et problem med eAccelerator er at instansvariabler deklarert med protected vil få eAccelerator til å krasje dersom en klasse som arver på denne forsøker å aksessere disse protected variablene. Løsningen på dette er å deklarere dem som public. Ikke spesielt god designmetodikk, men det fungerer…

En kort vinterferie i Trysil

21. februar 2007 · Comments Off

Jeg tok meg fri fra fredag, uke 7, til tirsdag, uke 8, for å ta meg en liten vinterferie. Hvor mye fri det ble på fredagen er en annen sak, siden jeg jobbet til langt på natt, faktisk helt til morgenen på fredagen, for å bli ferdig med det aller viktigste på et utviklingsoppdrag før jeg kunne ta meg en velfortjent ferie.

Dynka i snø

I helgen har jeg stått mye på slalåm, selv om det kanskje ble like mye afterski. Forholdene var ikke helt på topp. Det snødde mye både lørdag og søndag, med tett tåke på lørdag, som gjorde det vanskelig å se hvor man kjørte. Resultatet av dette var et lite fall etter at lårene mine ikke tålte alle humpene i bakken i større og større fart, da de var alt for “ødelagte” til at jeg orket å svinge så mye. Da var det deilig å ha Skihytta å komme til, og første pilsen var på bordet fem over tolv. Skal sies at vi var ute i bakkene halv ti. På Skihytta ble vi sittende en stund, kun avbrutt av en liten pub-til-pub-runde til Fageråsen før vi kom tilbake til Skihytta på afterski. Det var innleid en trubadur som spilte og sang, men for å være helt ærlig så var “pausemusikken” hakket bedre, en godfull Donald-imitator som sang med hele sjela og skapte god stemning på stedet.

På søndag merket jeg det harde føret fra dagen før, og det tok ikke lange tiden før lårene mine atter en gang var potetmos. Forholdene var noe bedre på søndag, så det gikk an å ta det litt mer med ro. Det ble en pub-til-pub-runde denne dagen også, med et stopp innom Knettsetra før vi tok turen videre til Fageråsen og endte opp på Skihytta. Det var tydeligvis ikke nok aktivitet i bakkene, for da vi kom hjem dro Magnus meg ut igjen og opp på taket for å hente capsen hans som vi kasta opp dagen før. For å toppe det hele så hoppa vi ut av vinduet i andre etasje og ned i løssnøen. Greit nok det, men jeg så vel egentlig ut som den avskyelige snømannen til slutt…

Magnus ga seg ikke

Dette er tredje helgen på rad som jeg har sått på slalåm. Det var deilig å få stått litt på slalåm igjen. Jeg ikke hadde muligheten til det i fjor, da jeg var syk i vinterferien da jeg var her oppe på Trysil.

Helgen har vært preget av mye ski, mye afterski, boblebad og film og musikk på full guffe. Jeg rakk ikke se hele Live 8 i vinterferien i fjor, men jeg klarte å se plate 1, 2 og 3 denne gangen, nå gjenstår kun plate 4, den får jeg ta når jeg kommer hjem. Jeg har fortsatt tilgode å se hele U2-konserten Vertigo på DVD, det har liksom alltid vært noe i veien…

Mandagen gikk egentlig bare med til surr, med PC, film og musikk.

Nå er det tirsdag, og det er snart på tide å dra hjemover. Jeg tar et stopp i Oslo og innom jobben på allmøte og så “Linpro-kveld”, for å få med meg foredraget om Jini og sosialisere med ansatte over litt øl og mat.