Verder zijn we ook net de kerstsfeer binnen gestapt.
Hopelijk bevalt het jullie.
Zou ik iets speciaals moeten zien, een soort kerst-thema ofzo? Want de site ziet er voor mij hetzelfde uit als voorheen :/.
Verder zijn we ook net de kerstsfeer binnen gestapt.
Hopelijk bevalt het jullie.
Zou ik iets speciaals moeten zien, een soort kerst-thema ofzo? Want de site ziet er voor mij hetzelfde uit als voorheen :/.
Ah MongoDB, dat was al een tijdje bekend.
Dat snap ik, maar er is een verschil tussen bepaalde passages onklaar maken en passages inhoudelijk aanpassen. Het eerste zou de voorkeur hebben, maar het laatste is wat er daadwerkelijk gebeurt.
Dit is toch een soort van escape-on-input (al worden de entiteiten in dit geval omgezet naar hun oorspronkelijke karakters en dat is in wezen decodering) en dat heeft eigenlijk nooit de voorkeur omdat je daarmee je (rauwe) input inhoudelijk aanpast terwijl je fratsen als XSS enzo simpelweg kunt vermijden door output te escapen (waarbij je dus niet je (rauwe) input aanpast).
Maar misschien gaat dit niet bij WYSIWYG-teksten waarin je mogelijk toch al in een rare spagaat zit (je wilt HTML toestaan, maar toch ook weer niet)?
Snap je wat er gebeurt in mijn oorspronkelijke bericht? Ondanks het feit dat ik niets inhoudelijk aanpas aan mijn tekst voert het systeem aanpassingen in deze tekst door, het is dus alsof ik A intyp. Als ik deze tekst open om te wijzigen staat er B, en als ik dit na opslaan nog een keer doe staat er C zonder dat ik zelf een letter heb aangepast... Als je het mij vraagt klopt dat niet.
Het lijkt er op dat Kromtech beveiliging echter niet erg serieus nam: Wachtwoorden waren gehashed met MD5 en zonder salt.
Maar dat is toch niet het directe probleem hier? De database is gelicht. Het is niet alsof de wachtwoorden van 13 miljoen gebruikers gebruteforced zijn? Het lek kwam waarschijnlijk op een andere manier tot stand en is op een andere manier uitgebuit (heb je ook een bron naar het Reddit artikel?). Het versleutelen van wachtwoorden middels MD5 is een bijkomstigheid. Gestolen is niet hetzelfde als gekraakt. Dit is zoiets als het onderscheppen van een geëncodeerd bericht: deze zul je nog moeten ontcijferen. En dat dat dan niet zoveel moeite kost, soit. Nat ben je toch.
MD5 als hashing algoritme voor wachtwoorden is al een tijd in onmin geraakt maar als je dan vraagt waarom dat zo is dan mompelen mensen iets over "rainbow tables" en "collisions" maar daar ligt volgens mij niet vaak (of in ieder geval niet altijd) de oorzaak dat gegevens ontvreemd kunnen worden. Zelden is er slechts één oorzaak maar is het een samenloop van factoren dat dit soort dingen mogelijk zijn. Daarnaast is volgens mij het gebruik van een salt niet per definitie veiliger (dit weet ik niet)?
Misschien was het wel zoiets banaals als SQL injectie of het gebruik maken van (andere) bekende veiligheidsgaten in verouderde software. Of een simpel root wachtwoord?
Anyway, heb je een bron naar het bewuste artikel?
Meh. Waarom zou je sommige HTML toestaan? Is het normaal dat WYSIWYG-editors dit soort omzettingen doen? Als ik jou goed begrijp ben ik al in een semi-HTML context aan het typen, waarom gaat deze editor dan alsnog met mijn entiteiten aan de haal?
Als ik het volgende invoer (zonder spaties)
& lt;
Dan is dit na een edit:
<
Zo ook als ik:
& amp; lt;
invul dan is dit na de eerste edit:
& lt;
en na mijn tweede edit
<
Dit lijkt mij niet de bedoeling?
Nog twee pointers:
#1
Indien je eenzelfde categorie producten hebt (bijvoorbeeld "schoenen") dan zullen er waarschijnlijk product-overschrijdende eigenschappen zijn, bijvoorbeeld "schoenmaat". Het is vrij belangrijk dat je voor die eigenschap (maat van een schoen) één eigenschap hebt, anders ben je mogelijk met verschillende maten aan het meten/zoeken als je per product zo'n eigenschap creëert. Het op een slimme manier vullen van deze generieke tabellen is dus minstens zo belangrijk als de structuur van de tabellen zelf. Deze flexibele opzet biedt je genoeg ruimte, maar je moet hier vervolgens wel handig mee omspringen.
#2
Bedenk vast welke pagina's je in je shop wilt laten terugkomen, denk aan:
- een categoriepagina
- een product(detail)pagina
- een pagina specifiek voor een zoekformulier; je zou ook kunnen overwegen om een filterpaneel/kolom/box te maken op een categoriepagina zelf
- checkoutpagina
en onderdelen als:
- filters
- wishlist
- loginpaneel zodat een klant niet altijd zijn/haar gegevens hoeft in te vullen
- shoppingcart
- crosssells / upsells
etc.
(nogmaals, kijk eens naar Magento voor inspiratie)
En bij dit alles (punt 2) als belangrijkste: houd hierbij je database in het achterhoofd, bedenk of test of de tabellen en de door jou hier ingestoken data geschikt zijn om aan alle "informatievragen" van de pagina's en onderdelen te voldoen. Maak bijvoorbeeld alvast een kleine set test-data waarmee je een kleine shop kunt simuleren en eventueel nog e.e.a. in het model kunt bijschaven voordat je de hele site al gebouwd hebt, hoe vroeger je dit soort wijzigingen/bijstuuracties doorvoert, hoe beter lijkt mij.
Zoiets dus:
Hierbij zou je dus product_variant_properties kunnen gebruiken om product_variant_property_values te kunnen vullen.
Wat je achtereenvolgens zult moeten doen bij het aanmaken van producten:
- maak een product aan
- maak product properties aan
- maak product property values aan
- EDIT geef in product_variant_properties aan uit welke eigenschappen een product bestaat
- vervolgens kun je concrete producten gaan bouwen door instanties van een product aan te maken in product_variants en deze (elk) te configureren (of deels te genereren) door gebruik te maken van product_variant_properties en de concrete waarden weg te schrijven in product_variant_property_values
Succes
Als je dan in de producten specificaties_ids de id's invoert gescheiden door "," oid kan je daar gewoon opzoeken en kan je ze met PHP ook exploden naar een array
Ai.
Toegegeven, daarmee los je het probleem van alle data in je database gooien op, maar hoe haal je dit er vervolgens weer uit. Er zijn wel situaties denkbaar waar het serialiseren van data handig is, maar hier lijkt mij dat heel onverstandig omdat je het jezelf haast onmogelijk maakt om informatie fatsoenlijk te zoeken. Als je een beroep moet doen op dit soort constructies dan is dat vaak een indicatie dat je data(base) nog niet helemaal uitgenormaliseerd is / incompleet is.
Dit schreeuwt haast om (op zijn minst) de introductie van een of enkele koppeltabellen.
Iets wat relatief weinig moeite kost en veel inzicht op kan leveren is het volgende: klieder eerst eens wat op papier. Noteer hierbij de "spelers" (de entiteiten) in het systeem. Schrijf daarbij op hoe hun relatie is ten opzichte van de andere spelers.
Bijvoorbeeld:
In mijn webwinkel verkoop ik producten. Een product heeft een aantal standaard en een aantal product-specifieke eigenschappen. Deze eigenschappen hebben specifieke waarden. Eenzelfde product heeft mogelijk meerdere uitvoeringen (sets van specifieke waarde-configuraties).
Met deze paar zinnen heb je al een redelijk nauwkeurig beeld geschetst van wat je zou kunnen bouwen en leg je mogelijk ook potentiële problemen bloot zoals variaties in de configuratie van "eenzelfde" product. Want, wanneer is een product hetzelfde? Bij een webshop lijkt het mij ook belangrijk dat bezoekers snel kunnen vinden wat ze zoeken. Je zult dus heel goed moeten nadenken hoe je dit vormgeeft.
Wat hierboven beschreven staat is in feite een soort van generieke opzet voor het bouwen van database-tabellen. Wat je hier in feite aan het doen bent is het bouwen van een database in een database. Nu is dit niet altijd de beste methode maar het is een methode. Omdat dit onder de motorkap in wezen een redelijk geavanceerd adminstratief systeem is loont het de moeite om je database ook echt relationeel op te zetten. Dit houdt in dat je ook (veelvuldig) gebruik maakt van (foreign) keys waarbij je onderlinge relaties afdwingt zodat de data in je database een consistent geheel vormt (en blijft) en relatief "makkelijk" onderhoudbaar is. Het is dus haast een must dat je dus de InnoDB engine gebruikt (aangenomen dat je van MySQL gebruik maakt).
In zijn simpelste vorm zou ik misschien de volgende tabellen gebruiken:
products
als kapstok voor producten
product_properties
als kapstok voor product-eigenschappen
product_property_values
hierin staan alle mogelijke waarden van een specifieke product-eigenschap
Met bovenstaande definties heb je (heel globaal) de spelers gedefineerd, maar nu moet je deze nog combineren tot concrete producten, dit zijn dus de invullingen van verschillende product-configraties, maar hier sta je dus voor een probleem. Stel je hebt een of ander T-shirt die in meerdere maten en meerdere kleuren beschikbaar is. Is dit één product die verschillende uitvoeringen heeft (en hoe organiseer je dat dan?) of behandel je dit als verschillende producten (maar hoe geef je dan aan dat er meerdere uitvoeringen zijn van dit zelfde T-shirt?). Omdat ik niet op voorhand weet hoe de situatie in jouw geval is en het in het algemeen wel verstandig is om je opties open te houden is het wellicht een idee om een extra tabel te introduceren waarin je de verschillende productconfiguraties van eenzelfde product kunt bundelen, dus bijvoorbeeld een tabel:
product_variants
kapstok voor verschillende eigenschapbundels van eenzelfde product. Er valt iets voor te zeggen om deze automatisch te genereren. Hoe je dit op interface niveau wilt inrichten... is een tweede verhaal, maar hier creëer je in ieder geval op administratief niveau de mogelijkheid. In principe bevat deze tabel de lijst met "concrete" producten.
Vervolgens moet je de eindjes nog aan elkaar knopen, zo kan het handig zijn dat je een (hulp)tabel hebt die aangeeft welke eigenschappen een product allemaal heeft, dit kan handig zijn om snel(ler) alle eigenschappen op te vragen zodat je hiermee op voorhand de ruimte op kunt spannen van eigenschappen waaruit een product bestaat wat weer handig kan om filters te bouwen om snel te zoeken binnen een productcategorie (hier komen we zo op terug). Als je bijvoorbeeld weet dat een zeker T-shirt type de volgende eigenschappen heeft: halstype, maat, kleur, opdruk, longsleeve (ja ofte nee) dan kun je hier op filteren om snel in te zoomen op het product waarin jij mogelijk geinteresseerd bent. Je zou ook kunnen overwegen om dit soort informatie op een of andere manier aan een categorie op te hangen waar dit kledingtype onderdeel van uit maakt. Je moet er dan vervolgens wel voor zorgen dat al deze producten op zijn minst deze eigenschappen bevatten zodat je hier op kunt filteren. De manier waarop je je informatie organiseert is dus heel erg belangrijk, anders kun je er op een gegeven moment niet goed in zoeken, wat tot gevolg heeft dat je producten minder goed vindbaar zijn en dat kan weer leiden tot afhakende kopers en daarmee tot omzetverlies. Daarom is het serialiseren van data wellicht niet zo'n strak plan :).
Maar goed, in eerste instantie een "simpele variant", wat je nog moet doen om het rondje compleet te maken is de eigenschap-waarden koppelen aan een product variant:
product_variant_property_values
Hierbij is het wellicht ook verstandig om in deze tabel op te nemen welke eigenschap dit betreft. In principe is dit afleidbare (redundante) informatie maar mogelijk zorgt dit ervoor dat het bouwen van queries en de uitvoer hiervan stukken gemakkelijker en sneller gaat. Zo ook dus de eerder genoemde tabel waarbij je de ruimte opspant van de eigenschappen van een specifiek(e) product(groep). Op zich is dit dus ook afleidbare situatie, maar op deze manier heb je ergens expliciet vastgelegd uit welke eigenschappen een product zou moeten bestaan:
product_variant_properties
Dit betreft dus een "abstracte hulptabel", hierin zitten geen concrete producten.
Hiermee heb je een mogelijke generieke basis. Daarnaast zou je hier nog extra lagen op kunnen bouwen door ook een soort van hierarchisch georganiseerde categorie-boom te bouwen waar je producten aan koppelt waarbij een product tot een of meer categorieën kan behoren.
---
Met dit alles vind je mogelijk wel het wiel opnieuw uit. Wellicht is het interessant hoe andere systemen (denk aan Magento) dit theoretisch aanpakken. Zij doen namelijk min of meer hetzelfde: daar heb je ook -zoals zij dat dan noemen- "simpele" en "configureerbare" producten (dit onderscheid wordt hierboven niet echt gemaakt, in ons geval zou een "simpel" product een product zijn met één productconfiguratie en een "configurable" is een product met meerdere productconfiguraties, nu ik er over nadenk is er iets voor te zeggen om deze verschillende soorten producten toch uniform te behandelen zoals we in deze opzet hier doen) en de data-organisatie zoals wij dit doen daar hanteert Magento een algemene variant voor: zij maken gebruik van een EAV-opzet (Entity Attribute Value), zij het op een, maar mijn mening, wat ondoorzichtigere manier.
Maar voel je vrij om hier zelf ook mee te experimenteren, houd er wel rekening mee dat de informatie die je in je database opslaat ook weer op een of andere manier (en bij voorkeur MAKKELIJK) opvraagbaar moet zijn.
EDIT: ik zal proberen nog een plaatje toe te voegen met alle tabellen en hun minimale verbanden (zullen zelf nog aangevuld moeten worden, maar dan zijn de relaties in ieder geval duidelijk). Ook zal pas blijken bij het "bouwen" van producten en het uitvoeren van (zoek)queries in je shop of het voorgespiegelde ontwerp echt handig is in het gebruik, of zoals ze zeggen "The proof of the pudding is in the eating".
Waarom stel je de naam van de afbeelding niet gewoon gelijk aan het user id?
Brein, dat zijn toch die loopjongens/moraalridders die ten strijde trekken voor de fossiele muziek- en filmindustrie?
Voorheen zag je wel eens zo'n sneu verhaal van een amerikaanse tiener die een boete van duizenden dollars moest betalen voor een illegaal MP3tje op zijn/haar iPod.
Zelfs deze opgepakte kerel is waarschijnlijk toch ook een "small fry" die als publieke zondebok en afschrikmiddel dient en die waarschijnlijk te onvoorzichtig te werk ging en daarbij zijn hoofd te ver boven het maaiveld uitstak. Vervolgens is dit dan een inkoppertje + gratis publiciteit voor de media-inquisitie.
Dit alles is gewoon kapitalisme ten top. In plaats van deze repressieve middelen zouden deze industrieën eens moeten komen met nieuwe businessplannen want ook (bijvoorbeeld) de meeste ingebouwde beveiligingen in CD, DVD of BluRay producten zijn vaak de dag van uitbrengen al achterhaald. Dit is gewoon investeren in de verkeerde zaken waarbij tevergeefs geprobeerd grip te houden terwijl ze de controle allang kwijt zijn.
Daarnaast slaat deze pesterij (ik heb er geen ander woord voor) ook te ver door de betalende consument:
- ik heb (betaalde) software voor het verwijderen van regio-gebonden DVDs en BluRays, ik kan anders geimporteerd materiaal niet kijken (oeh, regio's, laten we het daar eens over hebben)
- ik heb (betaalde) software voor het afspelen van deze DVDs en BluRays
- beide bovenstaande programma's moet ik eens in de zoveel tijd verlengen, ik blijf dus indirect betalen voor het gebruik
- op sommige muziek CDs zit een dermate vervelende beveiliging zodat ik hier niet eens MP3tjes voor eigen gebruik mee kan bakken
- bij het afspelen van deze DVDs en BluRays word ik eerst en na afloop minutenlang doodgegooid met (niet skipbare) intimiderende filmpjes over boetes en gevangenisstraf ingeval ik het in mijn hoofd haal een van de vele onduidelijke regels te overtreden
Tegenwoordig hebben we zoveel meer bandbreedte tot onze beschikking in vergelijking met tien jaar geleden dus als je de keuze hebt tussen een half jaar (waarbij je ook nog moet betalen) of twee minuten wachten (en je niets hoeft te betalen) totdat je een serie kunt zien. Ik begrijp dat de verleiding dan nogal groot is. Maar om daar hier dan zo te koop mee te lopen is nogal dom als je het mij vraagt. Vooral als je een voorbeeldfunctie (moderator) hebt.
Daarnaast is de hele mentaliteit van de consument ook behoorlijk verrot. Als het ondertussen een soort van sport is waarbij je opschept over hoeveel gestolen materiaal je bezit dan zit er ook ergens iets grondig mis in het mijn en dijn gevoel als je het mij vraagt.
Geïnteresseerden kunnen hier het mini-frameworkje downloaden. Wellicht maak ik hier ook nog een download met wat meer uitleg van op deze site.
EDIT: volg de instructies in de readme.php (dit bestand kun je rechtstreeks aanroepen)
EDIT: ik houd de downloads natuurlijk ook stiekem in de gaten he
Ugh, lees ook het commentaar bij dat script (het loginscript van @Frenzo.Brouwer) eens, het is (met cookies) nogal onveilig. Wat er aan HTML uitgespuugd wordt levert ook geen geldige HTML documenten op. Dat script leent zich ook niet bepaald voor uitbreiding.
In een poging van mij om van dat script alsnog iets te maken heb ik besloten om een nieuw loginsysteem te maken, maar dan wel goed :). Het is in principe een afgeslankte variant van een framework/CMS wat ik bij wijze van oefening aan het schrijven ben.
Als hier (bredere) interesse in is kan ik deze hier wel plaatsen. Alhoewel het systeem redelijk complex is, is het vervolgens wel redelijk eenvoudig om deze uit te breiden met eigen functionaliteit, maar dit is nu niet bepaald beginnersmateriaal.
Zeg maar je hoor, ik voel me een beetje een ouwe z*k als je u zegt haha.
Je zou een leuke blog kunnen schrijven over een project waar je nu mee bezig bent.
Dit kan dus van alles zijn? Als ik heel eerlijk ben zijn sommige blogberichten nogal kort en soms leggen ze lang niet alles goed of uitgebreid uit. Het is dan meer een verslag wat iemand ongeveer/precies gedaan heeft (maar niet waarom die aanpak is gevolgd).
Ook staat er in de regels:
7.3 Blogs dienen uniek te zijn voor ICTscripters.
Houdt dit in dat je artikelen die je hier plaatst ook nergens anders mag plaatsen? Dat vind ik een beetje een tekortkoming en zou voor mij een reden zijn om de artikelen dan maar op mijn eigen homepage of andere site te zetten.
Lolwut? Thanks! En nu? Ik zal je een PM sturen ofzo dan :].
Er deden volgens mij al vrij lang geleden geruchten de ronde dat deze plugin zo lek is als een mandje. Ik heb deze dan ook zo ingesteld dat ik altijd toestemming moet geven voordat deze geactiveerd wordt. Daarnaast is het (iig voor de Windows gebruikers onder ons) verstandig om een virusscanner en/of een anti-malware programma te gebruiken.
Overigens, het is verrassend*
verassen doe je bij een crematie
Illustratief voorbeeld, vele varianten en optimalisaties mogelijk, dit illustreert enkel het concept:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!-- use .min.js for minified version -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>
<style type="text/css">
body { font-family: sans-serif; font-size: 10pt; }
div.form div.item { display: block; line-height: 25px; }
div.form div.even { background-color: #eeeeee; }
div.form div.odd { background-color: #ffffff; }
div.form div.left { display: block; float: left; width: 20%; }
div.form div.right { display: block; float: left; width: 80%; }
div.form div.clear { clear: both; }
div.form ul { margin: 5px 0 0; }
div.form input { border: 1px solid; }
div.form input.error { border-color: #ff0000; background-color: #ffcccc; }
</style>
</head>
<body>
<div class="form">
<form action="" id="form_1" method="post">
<div id="messages"></div>
<div class="item even">
<div class="left"><label for="text_1">text field</label></div>
<div class="right"><input type="text" name="text_1" id="text_1" value="" class="validate-text" /></div>
<div class="clear"><!-- clear --></div>
</div>
<div class="item odd">
<div class="left"><label for="text_2">text field</label></div>
<div class="right"><input type="text" name="text_2" id="text_2" value="" class="validate-text" /></div>
<div class="clear"><!-- clear --></div>
</div>
<div class="buttons">
<button type="submit">submit</button>
</div>
</form>
</div>
<script type="text/javascript">
//<![CDATA[
$().ready(function() {
$('div.form').on('focus', 'input.validate-text', function(e) {
// hide previous errors
$(this).parent().find('.errors').slideUp(function() {
$(this).remove();
});
});
$('div.form').on('blur', 'input.validate-text', function(e) {
// show new errors
if ($(this).val() === 'test') {
// unflag as error
$(this).removeClass('error');
} else {
// flag as error
$(this).addClass('error');
if ($(this).parent().find('.errors').length == 0) {
$html = $('<div class="errors"><ul><li>input is not equal to "test"</li></ul></div>').hide();
$(this).parent().append($html);
$html.slideDown();
}
}
});
$('#form_1').submit(function(e) {
// trigger validation events
$('input').trigger('blur');
// check if we have errors
if ($('#form_1 .error').length > 0) {
e.preventDefault();
$('#messages').html('<p>one or more fields still contain errors</p>');
}
});
});
//]]>
</script>
</body>
</html>
Toon Meer
Voor een mogelijk wat beter leesbare variant zie hier.
Mja, maar zou het niet handiger zijn als dat hand in hand gaat? Ik bedoel, zit er enige structuur in hoe zo'n formulier wordt opgebouwd? Dan zou je in principe de jQuery-validatie code ook kunnen laten genereren.
Dit zou mijn voorkeur hebben: op deze manier wordt validatie centraal aangestuurd en schrijf je voor hoe het gedrag van je formulier is.
Wanneer je geen vast stramien hebt voor de opbouw van een formulier wordt dit elke keer maatwerk.
Een alternatief (of mogelijke implementatie van het bovenstaande) is dat je (automatisch) CSS stijl-klasses (of andere attributen) toevoegt aan de velden of veld-containers (binnen de scope van je form-container) die aangeven wat voor type veld het is en/of wat voor controle(s) er uitgevoerd dient (dienen) te worden. Vervolgens hang je aan deze stijl-klasses events die getriggerd worden bij (bijvoorbeeld) het verliezen van de focus waarna een of meer controles worden uitgevoerd. Dit stelde @Tim hierboven min of meer ook al voor. Volgens mij wordt deze werkwijze vaak gehanteerd in "checkouts" van Magento-webshops.
Het is misschien wel iets gebruiksvriendelijker als direct wordt aangegeven of iets verkeerd is ingevuld, maar omdat de gegevens sowieso (altijd!) aan de serverzijde gecontroleerd moeten worden (waar PHP het formulier verwerkt) zou ik daar eigenlijk eerst aandacht aan besteden.
JavaScript kan te allen tijde uitgeschakeld worden, vervolgens werken of je controles niet meer, of je hele formulier doet niets meer, met controles via JavaScript maak je je formulier hier ook (mede) afhankelijk van. Dit is vandaag de dag niet zo'n probleem meer (de meeste apparaten enzo ondersteunen dit meestal wel), maar in het kader van toegankelijkheid van je website is dit wel iets om mee te nemen (en hier dan ook bewust een keuze in te maken). In principe zou een formulier niet van JavaScript afhankelijk moeten zijn, maar je kunt ervoor kiezen dat je er vanuit gaat dat dit ondersteund wordt.
Dan de PHP kant van het verhaal, als je veelvuldig (standaard of zelfs maatwerk) formulieren moet opstellen wordt het misschien eens tijd om hier een soort van code voor op te stellen, oftewel een soort van formuliersysteem? Als je wat ingewikkelder formulieren maakt kom je trouwens haast niet om JavaScript heen maar dat wil niet zeggen dat je formulieren gebruiks-onvriendelijk worden als je de validatie aan de serverzijde doet. Als je de verschillende acties bij de interactie met een formulier een beetje opdeelt, en vervolgens alles aan elkaar knoopt met enerzijds je "formuliersysteempje" en anderzijds sessies waarin je tijdelijk formulierdata bijhoudt dan kun je best strakke formulieren in elkaar zetten. De code die je moet schrijven voor het genereren van een formulier wordt in combinatie met zo'n formuliersysteem ook meteen een stuk korter.
In zo'n formuliersysteem zou je bijvoorbeeld verschillende klassen kunnen schrijven voor het formulier in het algemeen, een abstracte klasse voor een formulierelement, en allerlei concrete subklasses die echte concrete formulierelementen implementeren. In die klasses kun je vervolgens weer regels opnemen (bijvoorbeedl door middel van methoden met een speciale prefix) die bepalen hoe een bepaald veld wordt gevalideerd. Deze formulier-genereer-code is dan ook meteen bruikbaar voor het wijzigen van data via zo'n zelfde formulier.
Ik heb al eerder hier ergens een voorbeeldje geplaatst, en alle bijbehorende code die je hiervoor moet schrijven, minus de formulierklassen uiteraard ;-), maar ik denk dat dit wel een redelijke indruk geeft van hoe je dit aan zou kunnen pakken.
EDIT: toegegeven, dit formulier gebruikt ook JavaScript en is hier dus ook afhankelijk van, maar dit formulier ontstijgt wel een beetje de standaard functionaliteit die een formulier te bieden heeft. Alle validatie vindt aan de PHP-kant plaats en hier komt dan terugkoppeling over als er iets niet in orde is.