Ik zit er aan te denken om nog eens wat in PHP te gaan doen. Als basis wil ik eerst en vooral een degelijk 'usermangement system' opzetten. Dit in een object gericht concept.
Omdat hierbij zowel het databaseontwerp als het implementeren van de code zelf belangrijk zijn, zou ik deze graag beiden bespreken.
De database zou ik als volgt willen inrichten:
Misschien kort even het schema toelichten:
In de database wordt over elke gebruiker wat basisgegevens bijgehouden. Er kunnen eventueel een aantal opmerkingen gemaakt worden over een gebruiker. (bv. zijn specifieke functie op de website). Verder is er verplicht een koppeling met de permissies tabel. Uiteraard, behoord een 'permissie-entry' altijd aan 1 specifieke gebruiker. (kleine opmerking hieronder) Verder worden alle belangrijke zaken die een gebruiker uitvoert gelogd. Tot slot is er nog een tabel met sessies in (Ik ben van plan een eigen session handler te programmeren die via de database werkt.) Elke sessie verwijst naar 1 gebruiker.
[opmerking permissies]
Ik overweeg dit nog wat aan te passen, namelijk een toevoeging: groups. Elke gebruiker krijgt dan een group en een group krijgt op zijn beurt een aantal permissies.
In PHP zou ik dan volgende klassen bekomen:
Session, User, Log, Note. Wat deze doen, lijkt mij vanzelfsprekend. Indien dat niet het geval zou zijn, wil ik dit gerust even toelichten.
Ja, en dan die klassen [php]Serializable[/php] (PHP core interface) laten implementeren. (mijn voorkeur gaat uit naar dit i.p.v. de magic methods __sleep en __wakeup te gebruiken)
Daar ben ik het niet mee eens. Waarom zou je het niet splitsen? Dit verhoogt naar mijn mening de flexibiliteit. Stel morgen maak ik een applicatie die maar een paar permissie instellingen kent. Overmorgen maak ik een totaal andere applicatie met meer complexe permissies. De 'functie' gebruiker is in beide applicaties hetzelfde, de permissies niet.
als ik een nieuwe applicatie schrijf, gebruik ik een nieuwe database. verder hoeft een database niet flexibel te zijn. een goede database is niet heel flexibel. normaliseren tot de max, en met queries de gegevens uitlezen, en ook meteen bewerken. lees ook eens deze tutorial. is bovengenoemde relatie een veel op veel, of veel op 1 relatie? nee, een 1 op 1. in mijn opzicht is het dan juist fout om die in een aparte tabel te zetten.
wanneer je zo gaat indelen om makkelijk uit te kunnen lezen, ben je fout bezig. databases zijn niet leuk, en zijn niet makkelijk. is dat wel het geval, moet je je achter je oren gaan krabben. de tabellen zijn maar het halve werk, de queries de andere helft. dat wordt vaak onderschat.
Ik heb zelf al een aantal boeken doorgenomen betreffende dit topic Jeroen. Vaak worden 1 op 1 relaties inderdaad weggefilterd. Maar dat wil niet zeggen dat het noodzakelijk is... Dit kan je in meerdere boeken terugvinden. Dit gedeelte van normalisatie kan je vaak zelf beslissen. Indien het zinnig is om een extra tabel te gebruiken, dan mag je dit doen.
In dit geval, beschouw jij dit als onzinnig. Ik vind dit echter wel zinnig. Hierover kunnen we natuurlijk uren discussiëren. Ik ben er vrij zeker van dat ik jouw mening niet zal kan veranderen, en eerlijk gezegd, jij de mijne ook niet :-). En dat is goed zo!
Moest ik nou overgaan naar een model met verschillende groepen (en dus bijhorende permissies), hoe zou jouw model er dan uitzien? (Want dit ben ik eigenlijk wel van plan.)
Ga je dan een tabel maken met groepen en daarin de permissies stoppen? Ga je ondanks die groep nog steeds alles bij een gebruiker bijhouden?
nee, hierin vind ik echt dat ik gelijk heb, en zo te zien kan ik jou niet overtuigen... (heel slechte reactie zou nu zijn om te zeggen dat je boek niet moet vertrouwen ;))
hoe bedoel je precies met groepen? dat een persoon tot een bepaalde groep hoort? dan heb je toch precies hetzelfde als nu.
of bedoel je dat een persoon tot meerdere groepen kan horen? dan veranderd het verhaal. de relatie veranderd dan namelijk van een 1 op 1 naar een 1 op veel. en ja, dan heb je een nieuwe tabel nodig ja. dan zou je gelijk hebben.
Ik doel erop dat elke gebruiker maximaal tot 1 groep kan behoren. (dus optioneel, maximaal 1) Dus dan pas je volgens jou niets aan.
Wat doe je in de volgende situatie: een billing applicatie. Je vraag aan een incasso bureau jou te helpen. Ga je dan enkel voor dat bureau een aparte groep gaan maken? Zou ik persoonlijk niet doen, want was is dan het nut van een groep? (Als ik me niet vergis noemt dit in de vakliteratuur totale disjunctie. Je behoort ofwel tot een groep ofwel heb je specifieke permissies. )
[size=xsmall]Toevoeging op 03/07/2012 16:11:44:[/size]
Wel toegegeven, dit staat -niet- zo beschreven in mijn startbericht. Dus het ERD klopt dan ook niet geheel meer.
Ik vind het op deze manier ook wel een beetje onzinnig. Een zinnigere methode zou ik vinden dat je permission groupen maakt, wat een groep wel/niet mag, en die dan in een aparte tabel zet. Dus:
Hierbij heeft User2 dus de rechten van een Guest (geen) en hebben User1 en User3 de rechten van een admin. Wat deze rechten precies zijn haal je dan uit de PermissionGroups tabel.
Ik kan me wel in dit model vinden, maar wat doe je dan als je zeer specifieke rechten aan één gebruiker wenst te geven?
Ik zeg nu maar wat, ik start een site op met wat mensen. Alleen, ik wil mezelf toegang geven tot een privé p* collectie (oké, absurd voorbeeld...), dan moet ik dus een extra groep aanmaken? Toch ook niet ideaal?
uhm.... ja, dan is denk ik een extra groep aanmaken toch beter... als we aannemen dat elke gebruiker ooit misschien tot die groep toebehoort, is het weer een grote groep.
Ja, dan zul je een groep moeten maken. En nee dat is niet niet ideaal, straks is er nog iemand met deze super-admin rechten en die kan dan ook mooi in de groep. Het heeft weer wat weg van de regel 'programmeren naar een superobject' altijd een basis hebben waar een User bijhoort is handig.
Jeroen, die groep zonder iets heet in mijn voorbeeldje 'guests'.