Upgrade naar php 5.3

Bijna een jaar geleden (30 juni 2009) kwam PHP 5.3 uit. PHP 5.3 wordt o.a. standaard geleverd bij Ubuntu 10.04 LTS (“Lucid Lynx”). Een upgrade van versie 5.2 gaf enkele problemen, hieronder een samenvatting. Sinds versie 5.3 ondersteunt PHP ook namespaces, juist daarmee hadden daarmee enkelen van de hieronder beschreven problemen voorkomen kunnen worden.

Nieuwe functies
Vanaf versie 5.3 zijn o.a de volgende functies beschikbaar getHostname en lcfirst. Beide functies waren al gedefinieerd in Opensourcecms. De eerste functie is hernoemt. Voor lcfirst is nu het volgende gebruikt:

if (!function_exists('lcfirst'))
{
function lcfirst($string)
{
return strtolower(substr($string,0,1)) . substr($string,1);
}
}

lcfirst() biedt afhankelijk van de lokale instellingen (via setlocale()) ook ondersteuning voor speciale teken zoals ë.

Regular expressions
PHP had altijd een eigen implementatie van Regular expressions (POSIX Regex Functions). Daarnaast kon ook gebruik gemaakt worden van regular expressions zoals die in Perl gebruikt worden (PCRE Functions). Van de laatste was al bekend dat deze vele malen sneller waren. Sinds versie 5.3 wordt dan ook afgeraden nog langer gebruik te maken van de POSIX Regex Functions, zoals ereg() en ereg_match(). Webapplicaties die bijvoorbeeld error level E_ALL gebruiken geven nu een waarschuwing.
Voor de verschillende foutmeldingniveaus in php (instelbaar via error_reporting()) kent php een aantal (voorgedefinieerde) constanten zoals E_ALL (2047). Sinds versie 5.3 komen hier de volgende constanten bij: E_DEPRECATED en E_USER_DEPRECATED. Daarmee kunnen dus de eerder beschreven foutmeldingen ook onderdrukt worden:

error_reporting(E_ALL ^ E_DEPRECATED);

Naast de POSIX Regex Functions worden sinds versie 5.3 nog een hoop meer functies afgeraden, zie hier voor een overzicht.

En misschien is het nog wel waar ook…..

Vanmiddag wees @birgerjansen mij op een leuke en vooral interessante blog; “Web Applications Should Be Compiled“. Reageren op het artikel kan niet meer. Zelf kan ik nog steeds niet reageren via twitter, dus dan maar op deze manier….

Zelf ontwikkel ik webapplicaties en websites in Opensourcecms.eu, wat is geschreven in PHP. Ontwikkelen gaat inderdaad snel. PHP is helemaal toegesneden op het ontwikkelen voor het web, dus dat biedt zeker voordelen voor ‘ad hoc’ implementaties. Performance issues spelen natuurlijk altijd een rol en in die zin zou compiled code absoluut een verbetering opleveren.

Bij de comments van het genoemde artikel wordt verwezen naar Mongoose. Mogoose is een webserver, m.i. in eerste instantie te vergelijken met bijvoorbeeld Jetty. Er van uitgaande dat de gecompileerde webapplicaties, tevens webserver zijn (onder port 80) kan het toch interessant zijn Mogoose nader te bekijken.

Goed stel; ik zou een webapplication framework willen bouwen, wat bij voorkeur ook direct inzetbaar is als CMS, in C of C++, wat zou ik dan nodig hebben. Beginnen ‘from scratch’, is meestal alleen leuker, maar niet per definitie efficiënter. De auteur van het artikel geeft de voorkeur aan C boven C++. Mijn mening is, wanneer herbruikbare code even snel geschreven kan worden als niet herbruikbare code, dan te kiezen voor het eerste. Naast C zou C++ dus zeker een optie zijn.

Zelf heb ik de volgende reeds bestaande projecten kunnen vinden:

Wexus Labs een C++ library voor web application development. Het idee achter Wexus lijkt duidelijk. Verder is mijn indruk dat er na 2006 weinig meer is gebeurd. Veel verder dan een ‘hello world’ wordt dan niet gekomen.

Wt, uitgesproken als ‘witty’, is zeker een interessant project. Wederom een C++ library. Zelf beschrijven ze het als een applicatieserver voor het ontwikkelen en onderhouden van webapplicaties. Goede indruk maakt natuurlijk, dat de site zelf gebouwd is in Wt. Nadere inspectie van de html-broncode wijst wel uit, dat Wt code produceert waarvan de zoekmachines waarschijnlijk niet echt blij worden….. na een korte analyse denk ik dat dit niet simpel op te lossen is. Wt lijkt mij bepalend in de uiteindelijke output. Webapplicaties die werken met en zonder javascript is natuurlijk mooi, maar voor het bouwen van websites is zoekmachineoptimalisatie (voor mij) ook belangrijk.

De meeste indruk maakte CppCMS op mij. Zoals ze zelf zeggen;
CppCMS is Free C++ Web Development Framework (not CMS) aimed for Rapid Web Application Development“. Het is dan op zichzelf geen CMS, er is wel een implementatie voor database-connectie(sql), sessies en caching. CppCMS lijkt mij een interessant project om binnenkort nog eens beter te bekijken.

Tot slot nog een vraag voor ‘de heren’ van CNOC. Hoe zien jullie de mogelijkheden wat dit betreft voor het ontwikkelen in Free pascal?

Wel of geen indexbestand?

Bij een website is de structuur te vergelijken met een directory- of mappenstructuur op een PC. Op een PC verwacht je bij het opvragen van een directory een lijst bestanden. Bij een website is het net iets anders. De meeste webservers tonen dan een bestand met de naam index.*. Dat kan bijvoorbeeld een .htm, .html of .php bestand zijn.
Op een apache webserver kun je de volgorde aangeven d.m.v. DirectoryIndex in de virtual host configuratie. Eventueel kan de instelling weer ‘overruled’ worden door het plaatsen van een .htaccess bestand in de betreffende directory.

Door deze constructie zullen voor een website /{subdirectory}/ en /{subdirectory}/index.htm verwijzen naar dezelfde content (bestand). Vanuit een zoekmachine gezien kan dit leiden tot ‘duplicate content’. Veel website tonen bij het opvragen van de domeinnaam een menu, waarop ‘home’ bijvoorbeeld verwijst naar /index.htm. Hoewel dit misschien een vreemd voorbeeld is bestaat het risico dat een zoekmachine beide URL’s gaat indexeren en deze vervolgens ziet als ‘duplicate content’.

Op een webserver kan dit worden opgelost door het opnemen van redirect. Dus als /index.* wordt opgevraagd krijgt de bezoeken een redirect naar / of v.v. Op apache is Mod Rewrite hiervoor zeer geschikt. Op Windows-machines is er tegenwoordig voor IIS 7.0+ ook een URL Rewrite Module beschikbaar.

Vraag is nu verwijst je op een website naar de /{subdirectory}/index.* of laat je het index bestand weg. Tot op heden heb ik altijd gedacht je hierin een vrije keuze had. Mij leek de enige voorwaarde consequent zijn. In de laatste versies van Opensourcecms.eu hanteerde ik de volgende strategie. Bij het opvragen van de domeinnaam wordt geen index bestand gebruikt, dus bijvoorbeeld http://www.bhmaat.nl/. Bij het opvragen van een ‘subdirectory’ moet altijd een index.htm gebruikt worden. Bijvoorbeeld: http://www.ingetrokkentepels.nl/nl/home/hoffman_exercises/index.htm. Uiteraard is dit een keuze waarover je kunt twisten. D.m.v. Mod Rewrite zorgde ik dat ‘verkeerde’ bestanden niet kon worden opgevraagd. Indien toch een aanvraag werd gedaan voor /index.htm(l) of /{subdirectory}/ gaf ik een redirect (response code 301) naar het juiste bestand.

De boven beschreven strategie werd niet alleen doorgevoerd in de virtual host configuratie. Opensourcecms.eu zorgde dat ook binnen een website de links klopte. In interne links, menu’s en broodkruimelpaden (breadcrumbs) verwees ‘home’ naar /. Overige links verwezen naar */index.htm. Ook werd dit doorgevoerd in zichtbare html-sitemaps, zoals http://www.lynxen.nl/nl/sitemap/index.htm en ook voor de xml-sitemaps. Een voorbeeld van het laatste is te vinden op: http://www.voedingsbeha.nl/sitemap.gz.

Ondanks dat de beschreven strategie mij correct leek heeft google moeite met het indexeren van de pagina’s die uitsluitend onder *index.htm worden getoond. Google biedt een aantal hulpprogramma’s voor webmasters, hier kun je o.a. jouw xml-sitemap uploaden en deze vervolgens laten analyseren.

Ook al staat in de sitemap aangegeven dat het opvragen van /{subdirectory}/index.htm gewenst is, vraagt de spider van google toch alleen /{subdirectory}/ op. Deze aanvraag wordt door verwezen via een 301 waarop google concludeert dat er sprake is van een doorverwijzing. Concreet leidt dit in de ‘Hulpprogramma’s voor webmasters’ tot een aantal waarschuwingen (gelukkig wordt nog gezien dat het geen fout is):

URL’s niet gevolgd
Tijdens het testen van een aantal URL’s uit uw sitemap hebben we vastgesteld dat bepaalde URL’s de gebruiker omleiden naar een andere locatie. We raden u aan URL’s in uw sitemap op te nemen die naar de uiteindelijke bestemming verwijzen (de bestemming van de omleiding) in plaats van om te leiden naar een andere URL.

Ondanks dat ik deze waarschuwingen niet terecht vind heb ik toch besloten voor de toekomstige versie van Opensourcecms.eu min strategie weer aan te passen. In hyperlinks zullen geen index.* meer voorkomen, index-bestanden kunnen uitsluitend nog opgevraagd worden via een */ request. Oudere versies van Opensourcecms.eu deden dat al. Dergelijke website zoals http://www.seksuelevoorlichting.be/ geven in de ‘Hulpprogramma’s voor webmasters’ van google geen waarschuwingen.

Sinds het begin van dit jaar is de volledige broncode van Opensourcecms.eu te downloaden op http://www.opensourcecms.eu/nl/download_en_installatie/index.htm. De zip-versie zal voorlopige nog de ‘oude’ strategie hanteren. Op de via cvs beschikbare code zullen de wijzigingen z.s.m. worden doorgevoerd. Weirdmaker.be zal de eerste website zijn, die van deze nieuwe aangepaste benadering gebruik zal maken.

Evaluatie Frog CMS

Op mijn eerder blog over Digitalus cms kwam een reactie om ook eens naar Frog CMS te kijken. Dat heb ik inmiddels gedaan. De installatie ging soepel en de performance van dit CMS bleek in eerste instantie uitstekend te zijn.

Installatie

Na het downloaden kan Frog CMS geïnstalleerd worden via de geleverde installer. In eerste instantie gaf die de volgende foutmeldingen:

Error: config.php must be writable
Error: public/ folder must be writable

Jammer, dat die controle niet werd uitgevoerd voor het invullen van de databasegegevens. Nu moest ik deze nog een keer invullen na het aanpassen van de rechten. Verder werkt het prima. Na de installatie had ik meteen een werkende website. Deze website (demo) is opgezet als een blog (Artikelen met archieven). Dit geeft in eerste instantie de indruk dat het CMS ook het beste gebruikt kan worden voor het schrijven van blogs. Als een blogartikelen aan een pagina koppelt heb je opeens een site. Zo groot is dat verschil dus niet. Bijvoorbeeld Expression engine en WordPress werken overigens ook op die manier.

Performance

Net als bij Digitalus cms heb ik voor Frog CMS ook naar de performance gekeken. Daarbij kijk ik dus naar het geheugengebruik en de rekentijd voor genereren van een pagina. Ik heb steeds dezelfde pagina gebruikt met dezelfde layout. De test is geen benchmark, maar wel een indicatie. Voor ik Digitalus cms testte had ik eerst een aanpassing gemaakt, zodat per pagina automatisch metatags werden aangemaakt. Dit heb ik ook eerst voor Frog CMS gedaan. Bij alle tests werd dezelfde php-class gebruikt voor het bepalen van de metatags (description en keywords). Voor Frog CMS heb ik de aanpassing in de layout gedaan. De resultaten waren verrassend:

Frog CMS:
<!– CPU usage user program: 0.048003 sec –>
<!– CPU usage OS for user program: 0.004 sec –>
<!– Total cpu usage: 0.052003 sec (user + OS)–>
<!– Memory usage totaal: 413,388 bytes –>
<!– Memory usage cms: 307,732 bytes –>
<!– PHP version: 5.2.8 –>
<!– Apache version: Apache/2.0.54 (Fedora) –>

Opensourcecms.eu:
<!– CPU usage user program: 0.092006 sec –>
<!– CPU usage OS for user program: 0.044003 sec –>
<!– Total cpu usage: 0.136009 sec (user + OS)–>
<!– Memory usage totaal: 1,708,364 bytes –>
<!– Memory usage cms: 1,468,084 bytes –>
<!– PHP version: 5.2.8 –>
<!– Apache version: Apache/2.0.54 (Fedora) –>

Frog CMS heeft dus een uitstekende performance. Het geheugengebruik is laag, minder dan een kwart van dat van Opensourcecms.eu. De rekentijd is slechts een tiende t.o.v. Opensourcecms.eu. Oeps, toch eens uitzoeken waar dat aan ligt.

Frog CMS heeft ook een cache module. De module slaat de complete pagina op en toont deze weer als er niets veranderd is. Uiteraard komt dat de performance ten goede, maar het is niet echt zinvol dit te vergelijken bovengenoemde tests. Gezien het een module is die niet tot de core van het systeem behoort is er wel het risico, dat het bekijken van de cache niet het eerste is wat het systeem doet. Op die manier zou er nog best wat rekentijd en geheugen verbruikt kunnen worden. Toch maar even de cijfers:

Frog CMS pagina uit de cache:
<!– CPU usage user program: 0.0080000000000027 sec –>
<!– CPU usage OS for user program: 0.004 sec –>
<!– Total cpu usage: 0.012000000000003 sec (user + OS)–>
<!– Memory usage totaal: 393,804 bytes –>
<!– Memory usage cms: 288,484 bytes –>
<!– PHP version: 5.2.8 –>
<!– Apache version: Apache/2.0.54 (Fedora) –>

De cache module levert dus wel een extra voordeel op.

In /frog/app/frontend/main.php wordt als eerste uitgevoerd:

// Intialize Setting and Plugin
Setting::init();
Plugin::init();

Daarmee is dus alleen niet gezegd, dat de cache plugin ook al eerste van de plugins wordt uitgevoerd. Ter vergelijking als ik de html van de pagina direct naar de browser echo:

<!– CPU usage user program: 0 sec –>
<!– CPU usage OS for user program: 0 sec –>
<!– Total cpu usage: 0 sec (user + OS)–>
<!– Memory usage totaal: 116,548 bytes –>
<!– Memory usage cms: 1,568 bytes –>
<!– PHP version: 5.2.8 –>
<!– Apache version: Apache/2.0.54 (Fedora) –>

Het installeren van deze plugin verliep overigens zeer eenvoudig.

Meertaligheid

De nieuwste versie van Frog CMS zou een betere ondersteuning hebben voor meertalige websites. Omdat ik nieuwsgierig was geworden door de goede performance, heb ik ook de laatste versie via SVN geïnstalleerd. Taal instellingen en vertaalmogelijkheden kon ik echter niet terug vinden. Op het form heb ik de volgende discussie hierover gevonden. De suggestie die gedaan wordt om de gehele websitestructuur te kopiëren en vervolgens te vertalen, lijkt mij geen optie. In de eerste plaats is het zeer bewerkelijk en bovendien heb je op die manier geen relatie meer tussen de vertalingen. Op een pagina kun je dus niet meer linken naar de vertaling van de betreffende pagina. De laatste post verwijst naar een WordPress Plugin met de naam qTranslate. Die aanpak lijkt mij veel beter. Voor Frog CMS zou dat beteken dat een dergelijke opzet niet alleen voor de pagina’s wordt gemaakt. Ook de artikelen gekoppeld aan een pagina zouden op deze manier opgezet moeten worden.

Pagina’s en artikelen

Na het installeren van Frog CMS vond ik het in eerste instantie verwarrend dat er een “Home” was waarop artikelen getoond werden van de pagina “Articles”. Waarschijnlijk is dit alleen als voorbeeld bedoeld. Aan “Home” kunnen net zoals aan “Articles” losse artikelen gekoppeld worden. Op die manier kun je dus prima een websitestructuur bouwen, met meerder artikelen per pagina. Het voorbeeld toont de artikelen op volgorde van toevoeging. Voor een website zou je dat dus niet willen. Het paginaoverzicht heeft ook de optie om te kunnen herschikken (drag and drop). Ik neem aan dat die volgorde ook gebruikt kan worden om de artikelen op de pagina’s te tonen.

Wat ik (nog) niet helemaal begreep. De “Articles” pagina is een pagina van het type archive. Toch bevat de inhoud van deze pagina een stuk php-code om de artikelen te tonen. Voor mij is niet duidelijk wat het nut van een pagina van het type archief dan is. Tenzij dit alleen bedoeld is om aan te geven dan het een archief is. Als dat inderdaad zo is, bemoeilijkt dit de inzet van Frog CMS voor het onderhoud van de site door niet php-programmeurs. Ik kan iemand vertellen, maak een pagina aan van het type archief. Als je dat gedaan hebt worden alle onderliggende pagina op die pagina als artikel getoond. Zou daar nog een stap bijkomen, voeg nu aan de content van die pagina het volgende stukje php-code toe, dan gaat dat net wat te ver. Ook voor wel php-programmeurs lijkt dat omslachtig.

Plugins / Modules

Om nog wat andere zaken te bekijken heb ik nog een extra module geïnstalleerd. Op deze pagina, is een flinke lijst met modules te vinden. Opvallend is dat veel modules gericht zijn op het systeem en onderhoud. De rest van de plugins voegen een eenvoudige functionaliteit toe. Complexere modules zoals een forum of een webshop zijn er niet.
Ik heb gekozen voor de “whois” plugin. De installatie was opnieuw eenvoudig:

1 – Unzip and upload this plugin to the Frog plugins directory.
2 – IF NECESSARY, edit the index.php file and change the variables.
All variables are well commented in the code.
3 – Access the Frog Administration screen and activate the plugin.
4 – Place the following code in your desired page: <? whois(); ?>

En zo werkte het ook. Ik kon dus een nieuwe pagina aanmaken en daarin de <? whois(); ?> code opnemen. Door deze manier van implementeren kan er dus nog steeds tekst boven of onder de module geplaatst worden. Ik had verwacht dat ik <? whois(); ?> code ook een een zgn. snippet (snipper) zou kunnen zetten. Dat kan ook, maar geeft in dit geval alleen content als de code in de content van een pagina wordt getoond. Plaats ik de snippet in de layout of in een artikel, dan wordt de inhoud niet getoond.
Verder neem ik aan dat er ook plugins zouden zijn die je aan een pagina koppelt. Op de manier van; deze pagina is van het type <plugin>. Eigenlijk net zoals bij de archive-plugin, die dus ook niet helemaal deed wat ik verwachtte.
Ondanks dat de <? whois(); ?> niet overal output geeft lijkt deze wel ‘globaal’ beschikbaar. Deze opzet zou er bij veel of grote plugins dus voor zorgen dat de performance hard achteruit holt.
Inderdaad is na het activeren van de plugin op alle pagina’s te zien dat de hoeveelheid gebruikt geheugen toeneemt:

<!– CPU usage user program: 0.032002 sec –>
<!– CPU usage OS for user program: 0.008 sec –>
<!– Total cpu usage: 0.040002 sec (user + OS)–>
<!– Memory usage totaal: 548,592 bytes –>
<!– Memory usage cms: 483,888 bytes –>
<!– PHP version: 5.2.8 –>
<!– Apache version: Apache/2.0.54 (Fedora) –>

Wanneer ik kijk naar de “Whois” plugin dan is deze niet geschreven volgens het MVC-patroon. Ook bij andere plugins zie ik dat niet terug.

Snippets / snipper

De website die met de installatie neergezet wordt heeft twee snippets. Via een snippet kan je klein stukjes content in een layout of pagina includen. De twee eerder genoemde snippets bevatten de header (inclusief) menu en de footer van de layout. Eigenlijk snap ik niet waarom deze opzet is gekozen, maar misschien is het alleen om te illustreren hoe een snippet werkt. De templates (layouts) bevatten veel php-code, eigenlijk past dat ook niet zo bij het MVC-patroon. Ook lijkt Frog CMS daarmee een systeem dat je alleen kunt beheren met php-kennis. Op het forum vond ik hier nog wat over terug, hier kun je lezen, dat je de php in snippets kunt plaatsen en zo de layout vrij van php kunt houden. Op de website van Frog CMS valt overigens te lezen dat het kunnen gebruiken van php in de layouts juist een uniek voordeel is. (waar heb ik dat eerder gehoord?)
Snippets lijken mij ook geschikt om de content van een plugin te tonen. Met de geteste “Whois”-plugin werkt dit dus niet.

Overigens kun je een pagina ook opdelen in verschillende stukken. Bij de standaard installatie heeft de pagina een body en een sidebar gedeelte. De sidebar kan dan in de layout worden opgenomen d.m.v. $this->content(‘sidebar’, true); Voor mij is niet helemaal duidelijk wat dan het verschil met een snippet is. Mogelijk biedt deze constructie de mogelijk om op elke pagina iets anders in de zijbalk te plaatsen.

Server farm

Zou Frog CMS in te richten zijn als server farm? De templates vormen geen probleem omdat deze in de database staan, op die manier kan elke website gewoon zijn eigen templates hebben. Qua plugins zie ik in eerste instantie geen eenvoudige oplossing. Feitelijk zou je twee plugin directories willen hebben, een in de centrale code en een per website. Verder is de opzet van de plugins belangrijk, dan met name de views. Views lijken er in eerste instantie dus niet te zijn. Zouden die er wel zijn dan zou het gewenst zijn, als per website aparte views per plugin gebruikt zouden kunnen worden. De de plugin staat centraal terwijl de views lokaal staan (of wanneer ze daar staan de centrale views overrulen).

Code

De code lijkt wel goed in elkaar te zitten. Alleen mis ik dus MVC bij de plugins. Documentatie heb ik ook niet kunnen vinden. Op de roadmap lees ik dat er aan PHPDoc documentatie wordt gewerkt. Voor PHPDoc zijn speciale comments in de code nodig en die zie ik inderdaad met grote regelmaat terugkomen.
Op de roadmap las ik ook “Removed split between frontend and backend”. Ik vraag mij af wat dit betekent. Mogelijk het idee om de content op de site zelf te kunnen aanpassen. Vanuit performace-perspectief is een splitsing tussen frontend en backend vaak de beste optie. Althans mijn idee is dat de performance van frontend belangrijker is, dus houd je die code vrij van beheerfuncties.

Conclusie

In eerste instantie was ik erg verrast door de goede performance. Later bleek dit mede te danken aan het minimaal aantal geïnstalleerde plugins. Een grote plugin kan de performance van de gehele site sterk verslechteren. Wanneer het
multi-language probleem aangepakt zou worden volgens de manier waarop ook de genoemde qTranslate plugin van WordPress is geïmplementeerd zou ik mij nog eens verder willen verdiepen in Frog CMS.

Reverse Ajax

Voor een project wil ik het volgende testen: door het oproepen van een URL met parameter, bijvoorbeeld http://www.w3masters.nl/opslaan/?woord=test, wordt de parameter opgeslagen in de database. Na het opslaan in de database wordt in een webapplicatie een pop-up geopend, die de opgeslagen parameter toont.

Dit betekent dus dat de webserver de data naar de webapplicatie (browser) moet pushen. Deze techniek heeft de naam Comet gekregen. (zie ook: http://ajaxpatterns.org/HTTP_Streaming) Het is daarbij niet wenselijk dat er steeds een mysql-query gedaan moet worden om te controleren over er nieuwe data is.

Om dit te bereiken is een extra Comet server nodig. De clients maken een connectie naar deze server en tonen een pop-ups als er nieuwe data beschikbaar is. Bij het samenstellen van de pop-up kan extra data uit de database worden opgehaald. Het script (php) dat wordt aangeroepen bij de eerder genoemde URL, schrijft de parameter naar de database en geeft het ID van de parameter door aan de Comet server. De clients ontvangen het ID en kunnen dus vervolgens de pop-up tonen.

Voor het opzetten van een comet server lijkt Jetty zeer geschikt. Jetty is opensource webserver geschreven in Java. Jetty bevat tevens een servlet implementatie van het Bayuex protocol van cometd. Cometd is een implementatie comet van de Dojo Foundation. Bij Jetty zittten tevens een aantal cometd demo’s, zie http://docs.codehaus.org/display/JETTY/Cometd+(aka+Bayeux). Net als de meeste andere comet voorbeelden, zit hier ook een chat applicatie bij. Met enige aanpassing zou deze applicatie de gezochte functionaliteiten kunnen leveren. Een eenvoudige “hello world” is hier te vinden.
Het Bayuex protocol voorziet niet in autorisatie en/of authentificatie. Autorisatie zou dus via de webserver zelf geregeld moeten worden. Jetty kan dit o.a. met JAAS, zie http://docs.codehaus.org/display/JETTY/JAAS.

Een alternatieve Comet server zou Comep kunnen zijn. Comep is een comet server geschreven in PHP. Comep levert ook enkele voorbeelden mee. Deze voorbeelden leken in eerste instantie niet te werken. Ook Meteor zou geschikt zijn, Meteor is geschreven in Perl. Meteor moet onder poort 80 draaien, wat een nadeel kan zijn als je deze dus wilt gebruiken op een server waar ook bijvoorbeeld Apache draait. De reden die hiervoor gegeven werd was dat Meteor anders vatbaar was voor cross-site scripting. Ik vraag mij af waarom dat op port 80 dan niet zo is? En als dat inderdaad niet zo is hoe dat dan zit met de andere hier besproken servers? Het artikel “Real Time Angst” geeft een zeer mooi voorbeeld van de kracht en mogelijkheden van Comet. Dit voorbeeld is ook op Meteor gebouwd. Hoewel ik dus niet opzoek was naar live data streaming is wel me wel duidelijk geworden dat Meteor een goed opensource alternatief is voor bijvoorbeeld het commerciële Lightstreamer.

Overigens lijkt een server zoals Jetty voor een eerste prototype van mijn project toch nog wat te complex. Het artikel
How to implement COMET with PHP” komt met twee eenvoudigere voorbeelden. De comet server is hier feitelijk een php-script in een ‘oneindige’ loop. Ook wordt geen gebruik gemaakt van het Bayuex protocol. Toch heeft het tweede voorbeeld wel ongeveer de functionaliteit die ik nodig heb. Je kunt regel tekst aan een .txt bestand toevoegen (in mijn geval dus het ID). Op de client wordt deze regel getoond, de laatst toegevoegde regel en alle regels die nieuw worden toegevoegd.

Evaluatie Digitalus cms 1.5 beta

Af en toe denk ik er over na om opensourcecms te herschrijven naar het Zend Framework. Er zijn natuurlijk veel php frameworks, toch lijkt Zend daarvan op dit moment de enige te zijn, die een standaard kan worden. Onlangs stuitte ik op Digitalus cms, dat reeds ontwikkeld is op het Zend Framework, het leek mij daarom interessant om eens te bekijken hoe de nieuwe 1.5 beta werkt en in elkaar zit.
Beta bleek al snel een groot wordt. Wat je krijg is de basis, met een installer die redelijk werkt. Pas na het lezen op het forum kwam ik er achter, dat de cache directory chmod 0777 moest hebben. Er wordt in deze beta slechts één module meegeleverd, de contact form module, die overigens niet werkt.
De reden om niet de stable versie maar de beta te testen is dat de stable versie in de eerste plaats niet gebouwd is met het Zend Framework. Ook beschikt de stable versie niet over de mogelijkheid een meertalige website te bouwen. Dit laatste is één van mijn minimale eisen.

MVC

Het cms maakt gebruik van het Model-View-Controller ontwerp patroon dat in Zend Framework geïmplementeerd is. Dit maakt de opzet van het systeem en de code overzichtelijk. In eerste instantie komt het vreemd over dat de views php-code bevatten. Dit is geen manco van Digitalus cms. Dit komt voort uit het Zend Framework. De ontwikkelaars van het Framework zeggen hierover: “PHP is itself a powerful template system”.

Artikelen en pagina’s

Wanneer je binnen het cms een pagina aanmaakt kan daar vervolgens met een html-editor, in dit geval WYSIWYG jQuery Plugin, content aan worden toegevoegd. Dat werkt prima. Zelf zou ik er de voorkeur aan geven om meerder artikelen per pagina te kunnen koppelen. Voordeel daarvan is dat je aan elk artikel apart extra functionaliteiten kunt koppelen. Op termijn zou dit opgelost kunnen worden via een aparte module.
Pagina’s kunnen slechts één module bevatten. Grootste nadeel daarvan is dat je geen content meer boven of onder de module kunt toevoegen. Dit probleem wordt opgelost door onder en boven de module een mogelijkheid te bieden, extra tekst in te voeren.

Automatische metatags

Bij Digitalus cms kan per pagina worden ingesteld wat de metatags (keywords en description) zijn, ook kan de titel van de pagina worden aangepast. Bij het beheren van meerdere website, met veel content wordt dit al snel te arbeidsintensief. Mijn voorkeur zou dan ook zijn dit net als bij Opensourcecms.eu te automatiseren.
De opzet van ./library/DSF/Builder/Action/Page.php maakt dit met een kleine aanpassing, mogelijk in de functie loadContent een aanroep te doen naar $this->setMeta en zo de metatags te maken op basis van de content die via de variabele content->content[‘content’]; beschikbaar is in deze functie.

Meertalige websites

Digitalus cms biedt de mogelijkheid om per artikel een vertaling aan te maken. Op de webpagina’s is dit zichtbaar te maken d.m.v. hyperlinks, die aangeven dat er ook een vertaling aanwezig is. Zelf zie ik de vertaling liever op een hoger (pagina) niveau, zodat niet alleen het artikel vertaald wordt maar ook de url, metatags (indien niet voor automatische metatags gekozen wordt, zie vorige paragraaf) en de menu’s op de betreffende pagina. Deze laatste optie, kan wel tot complexe situaties leiden, indien maar een gedeelte van de website vertaald is. Onmogelijk is het niet, zie bijvoorbeeld http://www.ellenpari.nl/

Modules

Ook de modules zijn opgezet volgen het MVC-partoon. Uitbreiding van het systeem, wordt daarmee eenvoudig en inzichtelijk. Wel vraag ik mij af hoe modules met meer complexere instellingen in de admin interface verwerkt moeten gaan worden. Binnen de interface lijkt wel ruimte te zijn gemaakt om een module in te stellen, maar niet om deze ook werkelijk te beheren, bijvoorbeeld in het geval van een webshop of forum.

Server farm

Installatie in een zgn. Server farm vind ik wenselijk. Hiermee bedoel ik dus dat er meerdere website opzelfde cms-code kunnen draaien. Mede door de MVC-implementatie zou dit mogelijk moeten zijn. In de huidige directory-structuur is hiervoor echter nog geen duidelijk onderscheid gemaakt. Het publieke deel (de feitelijk site) zou uitsluitend moeten bestaan uit templates, css, images en eventueel bijvoorbeeld een .htaccess bestand en een cache-directory.

Geheugengebruik en performance

Rekentijd en geheugengebruik krijgen bij cms-implementaties vaak weinig aandacht. Op zich is dat vreemd want in de eerste plaats bepalen deze factoren de laadtijd van de pagina. Daarnaast bepalen rekentijd en geheugengebruik het aantal gelijktijdige gebruikers dat een website of webserver kan afhandelen.

Ik heb een vergelijking gemaakt tussen Digitalus cms en Opensourcecms.eu, door een pagina te laden, met een artikel, menu, en ‘broodkruimel’-pad.

Digitalus cms:
<!– CPU usage user program: 0.248015 sec –>
<!– CPU usage OS for user program: 0.052003 sec –>
<!– Total cpu usage: 0.300018 sec (user + OS)–>
<!– Memory usage totaal: 5,184,296 bytes –>
<!– Memory usage cms: 5,127,524 bytes –>
<!– PHP version: 5.2.8 –>
<!– Apache version: Apache/2.0.54 (Fedora) –>

Opensourcecms.eu:
<!– CPU usage user program: 0.092006 sec –>
<!– CPU usage OS for user program: 0.044003 sec –>
<!– Total cpu usage: 0.136009 sec (user + OS)–>
<!– Memory usage totaal: 1,708,364 bytes –>
<!– Memory usage cms: 1,468,084 bytes –>
<!– PHP version: 5.2.8 –>
<!– Apache version: Apache/2.0.54 (Fedora) –>
<!– Database version: –>

Naast de langere rekentijd van Digitalus cms is te zien dat het geheugengebruik bijna 3x zo groot is. Mogelijke oorzaken hiervan zijn:

  • De overhead van Zend Framework
  • In de code kom ik veel nieuwe class/object initalisaties tegen, waar een Singleton misschien efficiënter zou kunnen zijn
  • Het cms lijkt voor elke pagina alle beschikbare ‘helpers’ e.d. in te laden terwijl ze niet allemaal nodig zijn
  • Hoewel het menu en ‘broodkruimel’-pad op een pagina vaak weinig veranderd, moet het elke keer opnieuw berekend worden, wat vaak gepaard gaat met rekenintensieve recursies.

Hoewel het niet openstellen van de cache-directory fouten gaf bij het installeren, lijkt de cache nu nog niet gebruikt te worden. Dit zou de performance kunnen verbeteren, als is er natuurlijk altijd iemand die de eerste pagina of zijn eerste pagina moet opvragen.

Opensourcecms.eu legt bij wijzigen in de pagina/websitestructuur een cache-bestand aan. Vanuit de in dit cache-bestand opgeslagen paginastructuur, kunnen menu’s, sitemaps en ‘broodkruimel’-paden worden samengesteld, zonder steeds opnieuw dezelfde queries naar de database te hoeven doen.

Code

De code van deze 1.5 beta versie is overzichtelijk en leesbaar. Mede door de inzet van Zend Framework ook consequent van opbouw. Documentatie van de code ontbreekt helaas nog volledig. Ook lijkt er bij de ontwikkeling dus nog weinig aandacht voor performance te zijn.

Conclusie

Digitalus cms laat zien dat er met Zend Framework een goed opgezet cms gebouwd kan worden. De keuze om een splitsing te maken in een public en admin deel, met elk zijn eigen views en controllers vind ik verhelderend. Het meenemen van meertaligheid vind ik goed, al is deze in mijn ogen dus nog niet ver genoeg doorgevoerd. Performance vraagt volgens mij nog wel aandacht. Zonder verdere verbeteringen zullen de vertalingen en menu-opzet op dit moment nog leiden tot het publiceren van ‘duplicate content’, wat dus ook nog aandacht vraagt.
Websites bouwen op een beta versie is natuurlijk sowieso geen aanrader. Zelf ga ik Digitalus cms i.i.g de komende maanden in de gaten houden.
De community lijkt overigens niet heel erg groot en/of actief te zijn. Daarnaast hoop ik dat de ontwikkelaars niet vergeten om eerste een stabiele basis te bouwen, voordat alle nieuwe en mooie functionaliteiten worden uitgewerkt.

PHP programming (tools)

Voor Opensourcecms.eu was ik op zoeken naar een meer professionelere aanpak en ontwikkelomgeving.

Ontwikkelomgeving

De eerste stap was de ontwikkelomgeving. Jarenlang heb ik gebruik gemaakt van de Zend IDE (Zend Studio). Dat leek ooit een goede keus, gezien dat bijvoorbeeld de mogelijkheid bood om Zend Encoder en Zend Guard te gebruiken. Twee tools om o.a. je code te kunnen beschermen en daar eventueel een licentie key aan te kunnen koppelen. Zend Encoder heb ik in het verleden wel eens gebruikt, maar de laatste jaren niet meer.

Na een tip die ik kreeg bij webdesiging.nl uit Nijmegen ben ik enkele maanden geleden overgestapt op Eclipse. Overigens wordt Zend Studio tegenwoordig ook aangeboden als plugin voor Eclipse. Ik heb gebruik gemaakt van het PDT Project (PHP Development Tools). Hiermee kon ik direct aan de slag. Tot op heden heb ik geen extra-plugins gedownload en bevalt het prima.

Versiebeheer

Tot op heden had ik uitsluitend een lokaal CVS Repository in gebruik. De maakte het voor andere lastig mee te ontwikkelen aan Opensourcecms.eu of zelfs om het te gebruiken. Ik heb er over gedacht om SVN te gaan gebruiken, maar tot op heden voldeed CVS ook prima. In plaats van zelf CVS te installeren heb ik gekozen om een account aan te maken op Sourceforge.net en daar gebruik te maken van de CVS. Het project is te vinden op: http://sourceforge.net/projects/opensourcecmseu/

Test-driven development

Test-driven development heeft zich de afgelopen jaren wel bewezen. Daar zou ik dus eigenlijk ook wel mee aan de slag willen. PHPunit is de tool die ik daarbij kan gebruiken. De documentatie geeft ook wat voorbeelden, die mij een beter idee geven voor het schrijven van tests. Test voor alle bestaande code schrijven leek mij niet te doen, maar ik heb mij wel voorgenomen, voor elke nieuwe bug en zoveel mogelijk voor nieuwe code wel tests te gaan schrijven.

Documentatie

De code wordt pas echt herbruikbaar en vooral overdraagbaar als deze voorzien is van goede documentatie. Phpdoc biedt de mogelijkheid deze documentatie automatisch te genereren. De documentatie wordt gemaakt uit de comments, die in de code staan. Het is even wennen en soms zoeken welke comments er moeten worden toegevoegd. Ik verwacht dat het wel snel routine zal worden.

Coding standaards

Het hanteren van de standaard voor coderen, houdt de code leesbaar en begrijpelijk voor andere programmeurs. Bij de ontwikkeling van Opensourcecms maak ik gebruikt van het Zend Framework. Daarom heb ik er voorgekozen om de Zend Framework Coding Standard for PHP te gaan gebruiken.
Checkstyle kan helpen de standaard te bewaken en overzichtelijk maken waar er van afgeweken is.
Verder is er voor Eclipse een speciale plugin voor Checkstyle. De komende weken moet ik nog testen of deze ook echt werkt en toepasbaar is op de Zend Framework Coding Standard.

Phpundercontrol

Phpundercontrol is een addon tool voor CruiseControl. Deze tools brengen veel van het bovengenoemde samen. het eindresultaat is een grafische interface, waar de documentatie te vinden is, die is samengesteld met Phpdoc. Verder wordt inzichtelijk gemaakt of de code de tests doorstaan (PHPunit) en hoeveel procent van de code gedekt is met een test (code coverage). Tot slot zijn ook de resultaten van Checkstyle terug te vinden. Gezien veel van mijn code nu nog niet voldoet aan de coding standards, geeft deze laatste tool enige problemen. Er kan in PHP nu niet voldoende geheugen gealloceerd worden om de Checkstyle over alle code uit te voeren.
Phpundercontrol gebruikt de laatste versie van de code uit het CVS Repository op Sourceforge.net.