Mijn idee van een PHP framework

Door AtleX op woensdag 19 december 2007 18:52 - Reacties (3)
Categorie: Development & code, Views: 7.316

We beginnen met een gevaarlijke stelling: de meeste PHP frameworks zijn niet best. Het is zo ongeveer de PHP hype van dit moment, frameworks maken en/of gebruiken, maar na een aantal frameworks bekeken te hebben in de afgelopen jaren kwam ik er snel van terug. Vaak lopen ze namelijk vast op een aantal punten:
  • Ze bieden teveel, als ik bijvoorbeeld clean URL's wil regel ik dat zelf wel
  • Ze dwingen je om op een bepaalde manier te programmeren
  • Ze houden (te) krampachtig vast aan legacy meuk. Waarom zou je nog PHP4 willen ondersteunen? PHP5 is al 3 jaar oud, PHP4 wordt binnenkort niet meer ondersteund en een hoster die geen PHP5 ondersteunt moet zich schamen.
  • Niet object geörienteerd
Bij bijvoorbeeld CodeIgniter liep ik er tegenaan dat de code zo ongeveer onbegrijpelijk is in best wat files, en ondanks dat ze beweren schitterende performance te bieden gaan de prestaties nogal achteruit als je flink wat onderdelen ervan gebruikt. Ook gebruikt een standaard instantie een whopping 650KB. Verder is het amper te strippen, als je na veel moeite onderzocht hebt welke onderdelen je kan verwijderen kan je dat nog een keer doen na het updaten naar een nieuwe versie van CodeIgniter.

Daarom heb ik ongeveer een jaar geleden besloten om langzaamaan mijn eigen framework in elkaar te draaien. Dat moest in ieder geval beschikken over de volgende features en eigenschappen:
  • Soort van namespace support, de toekomst van echte namespace support in PHP was tot een paar maanden terug erg onduidelijk en omdat ik er groot fan van ben wilde ik iets vergelijkbaars inbouwen.
  • Snel, CPU power is vaak afdoende voorhanden, disk I/O is bij veel servers al wat krapper. Mijn framework mag als default instance niet meer dan 175KB geheugen verbruiken, en disk I/O moet tot een minimum beperkt blijven.
  • Het moet te strippen zijn, dat kan je imho alleen bereiken met goede documentatie en een goede mappen structuur.
  • Het moest uitbreidbaar zijn.
  • OO, het is inmiddels enigzins volwassen geworden in PHP5 en dan moet je het gebruiken ook.
Gedurende een jaar ben ik bezig geweest dit te ontwikkelen, via een nogal afwijkend ontwikkeltraject. Ik ben begonnen met de absolute basis, en daarbovenop ben ik applicaties gaan bouwen. Per applicatie heb ik de dingen die ik miste toegevoegd, waardoor ik inmiddels een solide basis heb. Per nieuwe versie van het framework heb ik deze onder alle eerdere applicaties gezet, waardoor er inmiddels 8 webapplicaties gebruik maken van mijn framework in een productieomgeving.

Omdat een framework per definitie niet volledig geschikt is om onder een applicatie te schuiven moest mijn framework 'extendable' zijn. Bovenop mijn framework moet je het applicatie-specifieke geraamte kunnen zetten. Dat bied je de vrijheid om je applicatie op te bouwen zoals jij het wilt, terwijl je gebruik kunt blijven maken van de features van het framework.

Ook zijn niet altijd alle onderdelen van een framework noodzakelijk bij een applicatie. Deze onderdelen moeten volgens mijn bescheiden mening eenvoudig te verwijderen zijn. Dat heb ik bereikt door een duidelijke directory structuur te maken, waaruit simpelweg hele directories verwijdert kunnen worden zonder de applicatie te breken. Op dit moment is de absoluut minimale versie van mijn framework slechts 58KB, wat voor voor enkele website een belemmering qua disk usage hoeft te vormen.

Pseudo namespaces zijn zo ongeveer het paradepaardje van mijn framework. Ik heb gekozen voor de lamme oplossing qua implementatie. In een directory maak je mappen aan, en in die map maak je een PHP bestand met dezelfde naam als de directory aan die alle files van de namespace include. Beetje pauper misschien, maar het werkt, is eenvoudig te begrijpen en voldoet aan de eisen.

Bij het aanmaken van een nieuwe instantie van mijn framework doorzoekt hij de standaard namespace directory op zoek naar namespaces, en voegt deze toe aan een array, de namespace cache. Een 2e array houd bij welke namespaces er geladen zijn, om het dubbel inladen (= performance verlies) te voorkomen. Hierdoor heb ik in eerste instantie wel behoorlijk wat disk I/O nodig om de cache op te bouwen, maar daarna nog slechts een beetje bij het importeren van een namespace. Door de diskcache van met name Linux is dit na een paar uur gebruik amper nog merkbaar.

De gebruiker kan zelf ook directories met namespaces toevoegen, zodat het framework de mogelijk bied om zelf namespaces in je applicatie te gebruiken. Deze namespaces zijn exact hetzelfde te importeren als de standaard meegeleverde namespaces, waardoor de gebruiker slechts 1 methode hoeft te onthouden.

De meegeleverde namespaces voorzien in een aantal zaken die veel gebruikt worden, en om mijn framework eenvoudig en licht te houden liggen de criteria om in die lijstje opgenomen te worden nogal hoog. Een greep uit de standaard namespaces:
  • Een image manipulatie namespace
  • Een databaseconnectie namespace, voor MySQL & PostgreSQL. Deze classes bieden puur de mogelijkheid om verbinding te maken en queries uit te voeren
  • Een mail namespace, hiermee kunnen (HTML) emails op een veilige manier worden verzonden, inclusief bijlagen
  • Mijn benchmark- en profiler namespace, deze gebruik ik onder andere om de performance tests elders op deze weblog uit te voeren
Daarnaast zijn er nog een aantal namespaces optioneel toe te voegen, bijvoorbeeld:
  • Een feed reader, geschikt voor RSS en ATOM feeds
  • Een HTTP namespace, om GET, HEAD & POST requests uit te kunnen voeren
De gebruiker kan dus simpelweg zijn lijst met namespaces 'bij elkaar winkelen' om de door hem gewenste functionaliteit te krijgen.

Het framework zelf bied alleen de absolute basis functionaliteit. Zo worden GPC variabelen van hun eventuele slashes ontdaan, is er session support, wordt er wat informatie gegeven over de request (zoals de huidige opgevraagde pagina), en zijn er wat gegevens beschikbaar over de gebruikte serversoftware en de browser van de gebruiker. Ook hier geld weer, als de gebruiker meer wilt kan hij dat eenvoudig toevoegen door simpelweg mijn framework te extenden.

Door de overwegend positieve reacties op de gedachte achter mijn framework, de eenvoud en de bruikbaarheid ervan blijkt dat ik niet alleen sta met deze visie. Ik vraag mij dan ook af waarom er nog steeds gigantische frameworks verschijnen? De markt daarvan is al verzadigd, en er is duidelijk ook een doelgroep die wel zit te wachten op een light-weight framework dat uitbreidbaar en begrijpbaar is.

Volgende: Read-only public members in PHP 12-'07 Read-only public members in PHP
Volgende: We've got a winner (2) 12-'07 We've got a winner (2)

Reacties


Door Tweakers user krvabo, woensdag 19 december 2007 22:35

Bij het aanmaken van een nieuwe instantie van mijn framework doorzoekt hij de standaard namespace directory op zoek naar namespaces
Hmm zoals je zelf ook al aangeeft zorgt dat alsnog voor (onnodige) disk I/O, heb je er een adminpagina bij? Als dat zo is kun je misschien daar een "detecteer plugins" linkje ofzo neerzetten? :)
Scheelt weer I/O.

Klinkt verder wel interessant :)

Door Tweakers user Toolskyn, woensdag 19 december 2007 23:12

Volgens mij was het idee achter het Zend Framework in eerste instantie hetzelfde als jij hebt, daarom kun je ook nu nog bij dat framework alle klassen gewoon appart goed gebruiken en wordt er helemaal niets opgelegd om te gebruiken, gebruik gewoon wat je nodig hebt. Ook houdt het niet vast aan PHP4 support. En tja de hoeveelheid modules etc. Maakt dat nu echt wat uit? Wat je niet gebruikt wordt gewoon nooit geladen. Eventueel verwijder je het van je disk, lijkt me ook geen enkel probleem? Maar gezien elke host wel meer dan 50 MB aanbiedt lijkt me die paar MB aan extra klassen altijd leuk meegenomen. Dus weet je zeker dat je nu het wiel niet opnieuw aan het uitvinden bent?

Verder klinkt je framework wel interessant moet ik zeggen. Simpel + Klein + Uitbreidbaar blijkt elke keer weer een uitstekend trio om wat dan ook in op te bouwen (ook buiten de computerindustrie).

Door Tweakers user Muthas, zaterdag 12 januari 2008 22:26

Interessant artikel. Ik ben zelf ook bezig geweest met CodeIgniter en at first zag het er inderdaad goed uit. Maar qua performance had het eigenlijk toch wel een grote impact. Verder is die support die ze gewoon willen houden voor php4 onzin. Aangezien ik zelf niet echt een php-held ben, ben ik begonnen met het analyseren van CodeIgniter en mijn eigen versie daarop gebaseerd te maken. Alles wat mij overbodig leek eruit gehaald, en dat is best wat. De basis is vrijwel af, optionele classes (net zoals de voorbeelden die jij noemt) komen daarna.

Groot voordeel nu is dat ik de werking van m'n framework ook echt snap. Allerlei onzin die ik nooit gebruik (of überhaupt van het bestaan weet) zit er niet in.

Reageren is niet meer mogelijk