[PHP] OOP - Een klein CMSje (puur educatief!)

Pagina: 1
Acties:
  • 348 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
OOP - Object Geörienteerd Programmeren
Afbeeldingslocatie: http://gathering.tweakers.net/global/templates/got/images/layout/pixel.gif

Inleiding
OOP, staat zoals de meeste waarschijnlijk al weten voor: Object Orientated Programming. en OO staat voor Object Orientated.
OOP, is een manier hoe je je applicaties ontwikkeld. OOP brengt vele voordelen met zich mee, alle voordelen hier in een lijstje:
- OOP is zeer overzichtelijk (mits je het goed inplementeerd)
- Je code is voor veel dingen (en als het goed is) zonder aanpassingen in elke applicatie te gebruiken (hergebruik van je code dus)
- Je kunt blokken code afzonderlijk van elkaar testen
- Je ontwikkeld in hogere snelheden
- Dynamisch programmeren
- Veel objecten door anderen gemaakt, op internet te vinden en zonder aanpassingen te gebruiken
- in PHP5 uitgebreide mogelijkheden.

Aldus een inleiding die ook te vinden is op http://www.phphulp.nl
De testcase / vraagstelling
Afbeeldingslocatie: http://gathering.tweakers.net/global/templates/got/images/layout/pixel.gif
Nu komt de vraag. Waar (hoop ik) een hoop van te leren valt.

Stel, je hebt een klein CMSje. Het CMSje doet niets meer als Paginas toevoegen, pagina's verwijderen, wijzigen. Ditzelfde geld voor gebruikers (toevoegen, verwijderen, wijzigen), GebruikersRechten (toevoegen, verwijderen, wijzigen), Een bestandsbeheerdertje waarin bestanden geupload kunnen word, naam wijzigen, verwijderen e.d. En een mailmanager (waar alle mail in komt te staan die via het contact formulier verzonden word (+ Nog een keer naar een mail adres verzongen word))

Tot zover is alles duidelijk. Nu komt er nog een leuk iets bij, het systeem gaat gebruik maken van een héél simpel template systeem. Dit is 1 class.
Nu zeggen bepaalde mensen dat hiervoor het MVC pattern geschikt is (Model, View, Controller pattern). Dit is in mijn ogen niet zo zeer geschikt voor dit systeem, google levert een hoop hits op.

Om dit alles mogelijk te maken, moet je je gaan bedenken hoe je je classes gaat indelen, je bestandsstructuur e.d.

Nu komt de 1e vraag al, hoe ga je je classes indelen.

• 1 Class voor alle acties (Mysql query's e.d.?)
• 1 Class voor al het template meuk? (Dus de templates daadwerkelijk opvragen)



Of ga je classes maken voor elke sectie? (dus PerSection)?
• 1 Class voor Paginabeheer
• 1 Class voor Userbeheer
• 1 Class voor Bestandsbeheer

Echt heel duidelijk is dat niet, want elke class krijgt dezelfde functies bijna, die dan 'net' iets anders uitvoeren, dubbel werk lijkt het dan wel. Of je nu een pagina of een gebruiker toevoegt, zo héél veel verschil zit daar niet in, het word allemaal in MySQL weggeschreven.

Dus wat is nou de optimale manier om je classes in te delen? En wat ga je in die classes zetten. En welke functies ga je een class geven, Wat gaan die functies precies doen.
Vele mensen maken ook een extra class om bepaalde gegevens op te vragen over de user (is_logged_in e.d.?

Ik hoop eigenlijk een discussie te laten los barsten over bepaalde manieren van "oop" in PHP. En hoe andere mensen alles in zouden delen. Om zo een inzicht te krijgen in bepaalde opzichten van OOP.

[ Voor 6% gewijzigd door RedHat op 01-01-2006 12:33 ]


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Toevoeging op:
Binnen een class var's definieëren waarom???

Twéé voorbeelden, wat allebij werkt, waarom vars voordefiniëren?


Met voorgedefïeneerde strings/vars
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
var $iets;
class input {

    function input_time() {
        setlocale(LC_TIME, 'nl_NL');
        $iets = strftime ("%A %d %B, %Y");
        return $iets;
    }
    
    function printIT () {
        print $this->input_time();
    }
}
?>


Zonder voorgedefiniëerde vars
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

class input {

    function input_time() {
        setlocale(LC_TIME, 'nl_NL');
        $iets = strftime ("%A %d %B, %Y");
        return $iets;
    }
    
    function printIT () {
        print $this->input_time();
    }
}
?>


Het werkt allebij

Dus waarom voordefiniëren?

PS: De classnamen zijn niet optimaal maar gewoon snel voorbeeldje.

[ Voor 10% gewijzigd door RedHat op 01-01-2006 12:42 ]


Acties:
  • 0 Henk 'm!

  • Peter
  • Registratie: Januari 2005
  • Laatst online: 31-05 21:41
Voordefinëren is in mijn ogen wel nodig, in andere talen is dat het ook. Dat, en ze hebben het in de PHP mailing lists over het feit dat er strenger naar het voordefinëren van variable gekeken gaat worden.

Acties:
  • 0 Henk 'm!

  • knopper
  • Registratie: September 2001
  • Laatst online: 10-03 09:15

knopper

Sander Knopper

Zoals de code nu is lijkt het niet nodig om die variabele voor te definieren, echter als die variabele ook direct wordt gebruikt in andere functies v.d. klasse, maar denk bijvoorbeeld ook aan overerving e.d, dan is het ineens een stuk duidelijker waarom je die variabele wel moet definieren.

Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 06-06 09:54
RedHat schreef op zondag 01 januari 2006 @ 12:42:
Toevoeging op:
Binnen een class var's definieëren waarom???

Twéé voorbeelden, wat allebij werkt, waarom vars voordefiniëren?


Met voorgedefïeneerde strings/vars
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
var $iets;
class input {

    function input_time() {
        setlocale(LC_TIME, 'nl_NL');
        $iets = strftime ("%A %d %B, %Y");
        return $iets;
    }
    
    function printIT () {
        print $this->input_time();
    }
}
?>
Dit is toch niet logisch? De variabele $iets valt namelijk buiten de scope van de functie. Dus als je 'm daar voordefineert, dan heb je niets aan binnen de functie (daar bestaat 'ie nl. niet).

Bedoel je zoiets?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class input {

    function input_time() {
        var $iets;
        setlocale(LC_TIME, 'nl_NL');
        $iets = strftime ("%A %d %B, %Y");
        return $iets;
    }
    
    function printIT () {
        print $this->input_time();
    }
}
?>

[ Voor 7% gewijzigd door Skaah op 01-01-2006 13:16 ]


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class input {
var $iets;
    function input_time() {
        
        setlocale(LC_TIME, 'nl_NL');
        $iets = strftime ("%A %d %B, %Y");
        return $iets;
    }
    
    function printIT () {
        print $this->input_time();
    }
}
?>


dit bedoelde ik.

Maar graag ook reacties op topicstart :) veel moeite voor gedaan

Acties:
  • 0 Henk 'm!

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 09-06 06:07

JHS

Splitting the thaum.

RedHat over MVC:
Dit is in mijn ogen niet zo zeer geschikt voor dit systeem, google levert een hoop hits op.
En waarom niet :? .

Overigens had ik toen ik nog een framework in PHP trachtte te ontwikellen de volgende classes:

cBaseObject (Handige functie lib)
  cDal
  cBaseController
  cBaseModel, maakte gebruik van cDAL
    cBaseUser
    cBaseCache
  cBaseView
  cBaseRequestHandler (Loodste alles op basis van defaults en config langs C, M en V)
  cBaseParser (Gaf basis parser functies)
    cBaseTemplateParser (Templates gebaseerd op .tpl bestanden met inline html)
    cBaseDomParser (je kon in de classes mbv cBaseDomObject en aanverwanten een DOM-tree 
         opbouwen, waarna deze automagisch tot pagina geparsed werd)
    cBaseXmlParser (templates gebaseerd op een .xml (config) file)

[ Voor 71% gewijzigd door JHS op 01-01-2006 14:05 ]

DM!


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 01:41

MueR

Admin Tweakers Discord

is niet lief

Momenteel ben ik bezig met een iets uitgebreider systeem, maar dit is mijn opzet tot nu toe:

code:
1
2
3
4
5
class v3system (main class, bevat alle settings, alle andere classes worden op deze ge-extend)
-> class mysql (database class)
-> class userdata (sessie class, handelt alle userdata af, dus logins, permissions etc)
-> class errorhandler (spreekt voor zich...)
-> class smarty (Smarty template systeem)

[ Voor 16% gewijzigd door MueR op 01-01-2006 16:47 ]

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 06-06 09:54
RedHat schreef op zondag 01 januari 2006 @ 13:27:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class input {
var $iets;
    function input_time() {
        
        setlocale(LC_TIME, 'nl_NL');
        $iets = strftime ("%A %d %B, %Y");
        return $iets;
    }
    
    function printIT () {
        print $this->input_time();
    }
}
?>


dit bedoelde ik.

Maar graag ook reacties op topicstart :) veel moeite voor gedaan
Dit klopt ook niet. Nu heb je een eigenschap van het object gedefineerd; die je nergens gebruikt. (je hebt $this->iets gemaakt met waarde NULL). Als je persé wilt defineren, is het voorbeeld dat ik gaf (dus met de declaratie in de functie) het enige goede.

Ik weet trouwens niet eens zeker of dat kan; ik heb het nog nooit gezien en in de handleiding staat er ook niets over.

Acties:
  • 0 Henk 'm!

  • Peter
  • Registratie: Januari 2005
  • Laatst online: 31-05 21:41
Nee, wat Redhat zegt is wel goed, je defineerd de variable voor de gehele classe, jouw voorbeeld doet dat enkel voor de functie. Wel is het zo dat je er niets mee doet, iets als dit zou beter zijn;

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php 
class input { 
     var $iets; 
    function input_time() { 
         
        setlocale(LC_TIME, 'nl_NL'); 
        $this->iets = strftime ("%A %d %B, %Y"); 
        } 
     
    function printIT () { 
        $this->input_time(); 
        echo $this->iets;
    }
} 
?>

[ Voor 60% gewijzigd door Peter op 01-01-2006 14:05 ]


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
als je $this->iets echo't dan is $this->input_time() ook niet meer nodig dunkt me

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
class input { 
     var $iets; 
    function input_time() { 
         
        setlocale(LC_TIME, 'nl_NL'); 
        $this->iets = strftime ("%A %d %B, %Y"); 
        } 
     
    function printIT () { 
        echo $this->iets;
    }
} 
?>


zou dan ook moeten volstaan?

over topicstart:
Misschien iemand die zich loopt te vervelen: maak eens een class-structuur (pseudocode zonder acties alleen comments) hoe jij het zou oplossen.

[ Voor 24% gewijzigd door RedHat op 01-01-2006 14:15 ]


Acties:
  • 0 Henk 'm!

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 09-06 06:07

JHS

Splitting the thaum.

Redhat: Reageer ik, op verzoek, op je topicstart, negeer je me vervolgens :( ;) .

DM!


Acties:
  • 0 Henk 'm!

Anoniem: 42791

RedHat schreef op zondag 01 januari 2006 @ 13:27:

Maar graag ook reacties op topicstart :) veel moeite voor gedaan
Ik ben nog een beetje OO maagd, maar ik heb zelf vaak de neiging om uhm wat eens ergens 'noun identification' genoemd werd te doen, ofwel 'identificatie van zelfstandige naamwoorden'. In het geval van jouw CMSje zou je dus een User, Page en UploadFile klasse of iets dergelijks krijgen. Ik kan niet heel goed uitleggen waarom ik het zo zou doen. Ik heb het idee dat het ook als de applicatie mocht groeien overzichtelijker en logischer blijft. Overigens zou ik data access code (Mysql queries dus) wel in een aparte klasse stoppen. Ik heb dat in het systeem dat ik nu bouw als volgt gedaan.

- Noun identification. Zo kom ik bij mijn eigen app op o.a. een 'catalog' een 'user' en een 'application' klasse. Ik verdeel al deze potentiele klasses onder in een business en een data variant. Ik heb dus een BoCatalog en een DoCatalog klasse. In de BoCatalog klasse vind je ehm 'business logica' en in DoCatalog 'data logica', ofwel mysql queries die naar de server gestuurd worden. Tot slot werk ik met Smarty als template systeem en daarmee is het dus een volledig three tier systeem. Mijn ervaringen hiermee zijn erg positief. Code is erg makkelijk op te zoeken en ook debuggen gaat vaak erg vlot.

[ Voor 10% gewijzigd door Anoniem: 42791 op 01-01-2006 14:29 ]


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
JHS schreef op zondag 01 januari 2006 @ 14:19:
Redhat: Reageer ik, op verzoek, op je topicstart, negeer je me vervolgens :( ;) .
Ik zou zeggen, maak het iets uitgebreider, laat eens zien wat een class + functies erin voor functionaliteit en maak er een mooi textje bij wat OOP voor jouw betekend en hoe je het volgens jouw geïmplenteerd heb. Als je tijd hebt.

Wat doet je controller bijvoorbeeld?

Als je snel een pagina'tje maakt, hoe ziet jouw main-page eruit (index.php b.v.).

[ Voor 22% gewijzigd door RedHat op 01-01-2006 14:35 ]


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 02:03

alienfruit

the alien you never expected

Hmm, waarom

[ Voor 75% gewijzigd door alienfruit op 01-01-2006 15:12 ]


Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
RedHat schreef op zondag 01 januari 2006 @ 14:13:
als je $this->iets echo't dan is $this->input_time() ook niet meer nodig dunkt me

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
class input { 
     var $iets; 
    function input_time() { 
         
        setlocale(LC_TIME, 'nl_NL'); 
        $this->iets = strftime ("%A %d %B, %Y"); 
        } 
     
    function printIT () { 
        echo $this->iets;
    }
} 
?>


zou dan ook moeten volstaan?
Als je input_time niet aanroept, heeft $iets nog altijd een NULL waarde.
Dat kun je bijv. in de constructor dumpen :)

offtopic:
Leuk dat je phphulp.nl noemt :)
Ben lid van het phphulp team :+

Acties:
  • 0 Henk 'm!

  • Lurge
  • Registratie: Maart 2000
  • Niet online

Lurge

ActueleWind

ik heb ook een keer zoiets gemaakt samen met een vriend van mij (voor school). Misschien dat dat iets toevoegd? Het is gemaakt in PHP5 waar je het in je startpost ook over hebt. Het is wel ff geleden dus ik weet ook misschien niet exact meer waarom ik welke keuzes gemaakt heb (mochten er vragen zijn).

Afbeeldingslocatie: http://lurge.nettrends.nl/ontwerp.JPG

Werking klassen

• Main
Deze klasse maakt de klassen aan welke nodig zijn voor het afhandelen van de nodige acties om een Internetpagina correct weer te geven. Deze klasse maakt dus bijvoorbeeld de CMS klasse aan zodat deze de content kan afhandelen.

• User
Deze klasse is niet representatief voor een gebruiker, maar handelt zaken af welke met de gebruiker te maken hebben. Voorbeelden hiervan zijn het controleren en toewijzen van de rechten aan een gebruiker en het afhandelen van de login procedure.

• CMS
Is verantwoordelijk voor het afhandelen van het content welke weergegeven worden aan de gebruikers. In dit geval zijn dat alleen internetpagina’s (klasse Page) en wordt deze dus ook aangemaakt door CMS.

• AbstractPage
Hierin worden standaard methoden gedefinieerd welke noodzakelijk zijn voor het weergeven van een internetpagina. Een voorbeeld hiervan is de foutafhandeling welke op iedere pagina aanwezig moet zijn. Ook maakt deze klasse een instantie aan van DB zodat een verbinding met de database mogelijk is.

• Page
Hierin worden methoden gedefinieerd welke alleen bedoeld zijn voor één pagina. Dit houdt dus in dat iedere type pagina, bijvoorbeeld de zoekpagina, een eigen klasse Page heeft. Deze zullen dan allemaal een eigen benaming hebben welke representatief is voor hun functie en zullen allemaal overerven van AbstractPage.

• DB
Deze klasse bevat methoden welke het mogelijk maken dat er een “brug” ontstaat tussen een database en een internetpagina. Deze”brug” zorgt ervoor dat de klasse welke DB aanroept geen verstand hoeft te hebben van het type database en andere typische database eigenschappen.

• Config
Deze klasse bevat de configuratie welk e op dat moment geldt voor de website. Een voorbeeld hiervan is de database welke gebruikt moet worden.

• MySql/MsSql
Deze klasse bevat methoden welke het mogelijk maken om informatie uit de desbetreffende database te halen.

ActueleWind


Acties:
  • 0 Henk 'm!

Anoniem: 84120

Nu komt de 1e vraag al, hoe ga je je classes indelen.

• 1 Class voor alle acties (Mysql query's e.d.?)
• 1 Class voor al het template meuk? (Dus de templates daadwerkelijk opvragen)



Of ga je classes maken voor elke sectie? (dus PerSection)?
• 1 Class voor Paginabeheer
• 1 Class voor Userbeheer
• 1 Class voor Bestandsbeheer

Echt heel duidelijk is dat niet, want elke class krijgt dezelfde functies bijna, die dan 'net' iets anders uitvoeren, dubbel werk lijkt het dan wel. Of je nu een pagina of een gebruiker toevoegt, zo héél veel verschil zit daar niet in, het word allemaal in MySQL weggeschreven.
Je kan ook beide combineren: Classes voor basisdingen (Bijvoorbeeld Databasetoegang, uitvoer via template, invoer (beveiligd). En dan deze classes gebruiken in de overige classes. Daarmee bespaar je dus alle 'zelfde' code >> en daar is OO ook voor dacht ik zo.

Verder: Als je een userobject wil: Zou ik een goede sessie-manager maken (die meteen via DB werkt, waaraan je dat toevoegt, aangezien sessies meestal ngelijk staan aan user ingelogged/uitgelogged.

Wat ik heb:
- Classje Templatesysteem (3KByte ofzo, lekker snel/simpel)
- Classje DBsysteem (2KByte, word waarschijnlijk vervagen door PDO)
- Classje Sessionmanagement (3KByte)
- Classje Foutbeheer (slaat alles op in DB enzo, en vangt te grote fouten af, 2KByte)
- Classje Permissies (1Kbyte)

En dan heb ik ook nog een clasje die uitvoer kan opmaken als tijd/datum of bbcode en die spul (die is 3KByte)

Nou goed bovenstaande grotes zijn zonder comment :), maar is om aan te geven dat het mogelijk is om alles klein en simpel te houden zonder functionaliteit te verliezen. Ik erger me namelijk wel eens aan templatesystemen van 70KByte en aan Database-systeempjes die nog groter zijn. Houd er namelijk rekening mee dat dat ook allemaal ingelezen moet worden.

Verder heb ik een heel simpele opzet: Elke taak/groep taken één php bestand waarin die taken worden verwerkt (dus dat maakt bijvoorbeeld een account.php die accountactivatie, wachtwoord activatie (bij wachtwoord vergeten) en wachtwoord reset uitvoert: Allemaal gereguleerd via een simpel configbestandje.

Nog een tip: Houd het simpel, duidelijk en instelbaar.

Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Ik hoop in de loop van de week een mooi class-graph te maken en te posten hoe ik het zelf zou doen. En hoop dat ook commentaar op te krijgen. Dus hoop dat ik het deze week asap kan posten :)

Acties:
  • 0 Henk 'm!

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 09-06 06:07

JHS

Splitting the thaum.

RedHat schreef op zondag 01 januari 2006 @ 14:33:
[...] Ik zou zeggen, maak het iets uitgebreider, laat eens zien wat een class + functies erin voor functionaliteit en maak er een mooi textje bij wat OOP voor jouw betekend en hoe je het volgens jouw geïmplenteerd heb. Als je tijd hebt.
Ik vroeg ook vooral om een reactie op het feit dat ik me afvroeg wat je tegen MVC hebt :) .
Wat doet je controller bijvoorbeeld?
Mijn controller haalt data uit de Models en zet deze om in voor de View beschikbare en bruikbare data / variabelen :) . Het is echt een uitwerking van het MVC model. Maar ik zal later het wat verder uitwerken :) .

DM!


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Ik heb een klein deeltje al, comments?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class CMS_BASE
    function checkVar(); // checks var (options: email, name, is_numeric, automatically check for magic quotes)
        function connectDB(); // makes an connection to a mysql database
    function placeEnters(); // nl2br a specified string and returns the nl2bréd string
    function createTimeStamp(); // makes a nice timestamp (Options NOW(), and specified date)
    function SetPageTitle(); // Zorgt voor een gekozen titel

class Templateparser
    Functions for template parsing

class thisUser
    function isLoggedIn(); // checks for logged in, if not, then show login
    function showLogin(); // shows the login form to login
    function loginUser(); // This is for actually log in the user
    function logoutUser(); // This is for logging out the user
    function checkRights(); // Check rights for section (e.g. checkRights("can_modify_userinfo")
    function makeSession(); // make a sessionhash for cookie
    function getUserData(); // This is for getting userdata from mysql (like firstname)
    function checkActive(); // Is this user active? Or set to non_active?

Acties:
  • 0 Henk 'm!

  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 11-06 21:55
@RedHat: ik weet niet of je de volgende topics al hebt door genomen, maar wellicht staat er voor jouw relevantie informatie in. Het betreft, [PHP(5)] Ervaringen met diverse Database Abstraction Layers en [PHP,OOP] Mijn eerste klasse - wat erbinnen en wat erbuiten?.

Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Als er iemand nog een class indeling wilt maken zoals hierboven feel free :)

Ik denk dat het goed is om dingen te laten zien en van elkaar te leren.

Dit hierboven, is puur educatief een opzetje (wat nog nie helemaal okay is (niet helemaal = understatement)) maar ik wil wel n's zien hoe andere mensen nou een opzet maken zoals heirboven.

Acties:
  • 0 Henk 'm!

  • aex351
  • Registratie: Juni 2005
  • Laatst online: 11-06 20:43

aex351

I am the one

Classes deel je in op je eigen kennis en ervaring. Je kan hierbij al bestaande patronen gebruiken. Wel fanatieke startpost voor 1 vraag trouwens.

[ Voor 20% gewijzigd door aex351 op 02-01-2006 20:21 ]

< dit stukje webruimte is te huur >


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Heb er ook wel wat moeite voor gedaan, aex351 ik snap je reaktie toch vind ik hem een beetje misplaatst. Zoals je kon lezen kun je op een hele hoop manieren zoiets invullen. Maar het gaat erom hoe vult iemand dit in, met motivatie. En hoe ga je dingen aan elkaar linken als het ware. Ik ben benieuwd.

Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Ik ga even een voorbeeldje geven van een userclass....
Het werkt allen nog niet (onderaan de file, hij pakt hem niet, $_COOKIE['session'] = wel aanwezig)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
mysql_connect(); // notshowing :)
mysql_select_db(); // not showing :)
class thisUser {

    var $thisUser;
    var $userSpec;
    

    /* == (is_logged) Checks if user is logged in == */
    function isLogged () {
        if (isset($_COOKIE['session'])) {
            $this->isLogged = TRUE;
        }
        else {
            $this->isLogged = FALSE;
        }
    }

    /* == (valid_user) Checks if user is valid logged in == */
    function validUser () {
        $thisUser = mysql_query("SELECT * FROM Users WHERE userID = ' " . $_COOKIE['userid'] . " ' AND userSession = ' " . $_COOKIE['session']) or die (mysql_error());

        if (mysql_num_rows($thisUser) == 0) {
            return TRUE;
        }
        else {
            return FALSE;
        }
    }
    /* == (get_user) Get userinfo == */
    function getUser ($userSpec) {
        $thisUser = mysql_fetch_assoc($thisUser);

        $getUserInfo = array (
                        'userID' => $thisUser['userID'],
                        'userName' => $thisUser['userName']
        );

        return $getUserInfo[$userSpec];
    }
}

$newUser = new thisUser;
if (!$newUser->isLogged) die ("Not logged in mate");
if (!$newUser->validUser) die ("No valid login");

echo $newUser->getUser("userName");

            

?>

Acties:
  • 0 Henk 'm!

  • PowerSp00n
  • Registratie: Februari 2002
  • Laatst online: 26-05 09:20

PowerSp00n

There is no spoon

RedHat schreef op maandag 02 januari 2006 @ 21:23:
Ik ga even een voorbeeldje geven van een userclass....
Het werkt allen nog niet (onderaan de file, hij pakt hem niet, $_COOKIE['session'] = wel aanwezig)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

    /* == (valid_user) Checks if user is valid logged in == */
    function validUser () {
        $thisUser = mysql_query("SELECT * FROM Users WHERE userID = ' " . $_COOKIE['userid'] . " ' AND userSession = ' " . $_COOKIE['session']) or die (mysql_error());

        if (mysql_num_rows($thisUser) == 0) {
            return TRUE;
        }
        else {
            return FALSE;
        }
    }
}

$newUser = new thisUser;
if (!$newUser->isLogged) die ("Not logged in mate");
if (!$newUser->validUser) die ("No valid login");

echo $newUser->getUser("userName");

            

?>
Wat 'pakt hij niet'? Maarum, als er geen matchende users gevonden zijn returned 'ie true? -> No valid login? Of zit ik te slapen? :+

Acties:
  • 0 Henk 'm!

  • aex351
  • Registratie: Juni 2005
  • Laatst online: 11-06 20:43

aex351

I am the one

Wat is je vraag op de class? aangezien ik niet begrijp waarom je dat nu post. Zit trouwens ook vol met fouten.

Of vraag je aan ons om je fouten eruit te halen ?

[ Voor 20% gewijzigd door aex351 op 02-01-2006 21:48 ]

< dit stukje webruimte is te huur >


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 08:19
Waar ik altijd tegenaanloop is dat het door de statelessness van het HTTP protocol vaak onzin is om classes te maken die zinnig zijn in een applicatie. Een uitgekristalliseerd user-object is in negen van de 10 gevallen onzin omdat je helemaal niet hoeft te weten dat Jantje username "ploert" heeft en in Den Helder woont. Zolang Jantje zijn gegevens niet wil wijzigen heb je er voldoende aan te weten dat hij is ingelogd, danwel dat hij admin-rechten heeft.

De meest (her-)bruikbare klassen zijn imho in PHP dan ook de klassen die juist acties voorstellen die je als programmeur graag gegroepeerd ziet. Database acties, inloggen, templates, url-afhandeling. In wezen dus gestuctureerd functioneel programmeren. Het voordeel dat je de status van een object kunt uitlezen verdwijnt toch binnen de halve microseconde die je request duurt.

Tot zover de knuppel in het hoenderhok...

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

T-MOB schreef op dinsdag 03 januari 2006 @ 03:16:
In wezen dus gestuctureerd functioneel programmeren.
Functioneel programmeren is niet wat jij denkt ;) Je bedoelt volgens mij procedureel.
Het voordeel dat je de status van een object kunt uitlezen verdwijnt toch binnen de halve microseconde die je request duurt.
De levensduur van een request lijkt me nou niet direct een argument voor het een of ander.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Ik zie zo al dat je een paar duidelijke fouten maakt. Bij OO is het erg belangrijk (en bij prodecureel ook overigens) om goed na te denken wat je een class of functie/method wilt laten voorstellen. Je hebt nu bijvoorbeeld een class thisUser, die moet logischerwijs de huidige user voorstellen. Als je dan naar de methoden kijkt die je in de class stopt, dan zie je dat ze conceptueel niet kloppen bij wat je wilt laten voorstellen met je user.

Je maakt ook een fout bij wat je je functie wilt laten voorstellen. Je hebt bijvoorbeeld de functie validUser, welke als taak heeft (zou moeten hebben) om aan te geven of het user object een valide user voorstelt. Dat is echter niet het enige wat het doet, het laad daarnaast ook nog eens de record data in, in het veld thisUser::$thisUser. Je leest daarna binnen getUser() die record data weer uit, wat betekent dat getUser volledig afhankelijk is van validUser terwijl ze niets met elkaar te maken hebben. Probeer het eens te bekijken vanuit het oogpunt van iemand die jou code voor het eerst ziet. Ziet het er dan logisch en in 1 oogopslag duidelijk uit? Enkele van de punten die je in je start post gaf zijn namelijk wel volledig afhankelijk van deze criteria (naast nog meer).

Ik zal er even verder op ingaan. Om validUser duidelijk te maken zou je hem nu eigenlijk een andere naam moeten geven. En dan een naam die volledig (of zo volledig mogelijk) beschrijft wat de functie doet. Je zou dan denk ik eerder iets als dit krijgen:
PHP:
1
function loadDataOfThisUserForGetUserMethodToUseAndReturnIfThisUserIsValid() /*...*/

Ok, mischien is het overdreven om hem zo'n lange naam te geven, maar als je je code zo schrijft dat 2 functies op een dergelijk manier van elkaar afhankelijk zijn en ze daarnaast ook nog eens verschillende taken geeft, dan moet je het wel duidelijk maken. Beter is dus om zoiets los van elkaar te zetten. Het is sowieso goed om een functie 1 enkele taak te geven. validUser heeft er nu dus 2, die in princiepe weinig met elkaar te maken hebben (conceptueel).

Nog iets vreemds dat ik op te merken heb is dat je thisUser een method getUser geeft. Dat zou goed kunnen als die functie dan ook werkelijk thisUser objecten terug geeft. Maar dat doet hij blijkbaar niet. Hij geeft gewoon een array terug met gegevens op een bepaalde user. (Geen idee waar die userSpec voor is overigens.) Beter is het om een aparte class te maken die de beheer van de user regelt, en daarnaast een User class die dan ook echt een user voorsteld.

Je maakt ook een fout bij het aanroepen. $this->isLogged roept namelijk niet de functie isLogged aan binnen thisUser. Hij probeert daarentegen gewoon het attribuut $isLogged van thisUser op te halen. En die is blijkbaar alleen geset als je eerst isLogged() hebt aangeroepen. Beter is om er gewoon een getter van te maken die een boolean returned. (en dan $isLogged helemaal weg te laten of die een waarde te geven in de constructor. Het is verder sowieso niet netjes om attributen direct op te halen, dat kun je beter via een getter functie doen (omdat je de waarde later mischien op een andere manier wil achterhalen, bijvoorbeeld door 2 waarden te combineren etc. encapsulation gaat daar over).

Een kleine rewrite zou dit kunnen geven:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php

class User {
    var $userID;
    var $username;
    var $session;
    
    function User($userID = null, $username = null, $session = null)
    {
        $this->userID = $userID;
        $this->username = $username;
        $this->session = $session;
    }
    
    function getUserID() {
        return $this->userID;
    }
    
    function getUsername() {
        return $this->username;
    }
    
    function getSession() {
        return $this->session;
    }
    
    function isLoggedIn() {
        return isset($_COOKIE['session']) && $this->session == $_COOKIE['session'];
    }
    
    function isValid() {
        return !is_null($this->userID);
    }
}

class UserManager {
    function getCurrentUser() {
        $user = UserRepository::getByUserIDAndSession($_COOKIE['userid'], $_COOKIE['session']);
        return is_null($user) ? new User() : $user;
    }
}

class UserRepository {
    function getByUserIDAndSession($userID, $session) {
        $query = "SELECT * FROM Users WHERE userID = '" . $userID . "' AND userSession = '" . $session . "'";
        // fout -> return $this->createUserFromQuery($query);
        return self::createUserFromQuery($query);
    }
    
    function createUserFromQuery($query) {
        $result = mysql_query($query) or die(mysql_error());
        if ( !( $record = mysql_fetch_assoc($result) ) ) return null;
        return new User(
            $record['userID'],
            $record['userName'],
            $record['userSession']
        );
    }
}

$currentUser = UserManager::getCurrentUser();
if (!$currentUser->isLoggedIn()) die ("Not logged in mate");
if (!$currentUser->isValid()) die ("No valid login");
echo $currentUser->getUsername();

?>

Ik heb nu de taken verdeelt over 3 classes. User stelt enkele en alleen een User voor. UserManager heeft als taak alles omtrent User te regelen, wat een User zelf niet zo veel aangaat. Het verkrijgen van de huidige user bijvoorbeeld. Dat doet die class weer door gebruik te maken van een andere, namelijk UserRepository (wat een soort in memory set moet voorstellen, maar wat eigenlijk de set user in de database representeerd), omdat ik UserManager niet wil koppelen aan de database. Mischien wil ik voor test cases wel puur een array met users gebruiken. Om zoiets voor elkaar te krijgen moet je nog verder gaan loskoppelen. Als je dat wilt weten laat ik het wel even zien.

[ Voor 14% gewijzigd door Michali op 03-01-2006 20:17 . Reden: Klein stukje code gewijzigd ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Not Pingu
  • Registratie: November 2001
  • Laatst online: 09-02 20:11

Not Pingu

Dumbass ex machina

T-MOB schreef op dinsdag 03 januari 2006 @ 03:16:
Waar ik altijd tegenaanloop is dat het door de statelessness van het HTTP protocol vaak onzin is om classes te maken die zinnig zijn in een applicatie. Een uitgekristalliseerd user-object is in negen van de 10 gevallen onzin omdat je helemaal niet hoeft te weten dat Jantje username "ploert" heeft en in Den Helder woont.
Die gedachte had ik ook ooit mbt. ASP.NET. Want je objecten 'leven' toch nooit langer dan 1 request dus zul je iedere keer opnieuw die dingen moeten aanmaken. Maar als je eemaal ermee aan de slag gaat, dan kom je erachter dat het een heel mooi systeem is om abstractie te creeeren tussen al je lagen. Je kunt een object heel makkelijk doorsturen van je datalaag naar je businesslaag naar je pagina's.

Voorbeeld: Je maakt een groot object met al je data voor een pagina. Dus iets als:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class PageInfo
-------------------
Id
Title

Owner
--UserId
--UserName

UserAccess[]
--UserId
--CanEdit
--CanView
--CanDelete

Template
--Title
--FilePath
--Panel[]
----PanelName

PageItem[]
--PanelName
--Content


Implementatie gewoon ter plekke uit mijn neus gezogen, beetje afgeleid van IBuySpy / DotNetNuke. Je zou zelf misschien een hele andere rechtenstructuur kunnen gebruiken ofzo, maar bear with me.

Je haalt in je DAL ineens het hele zwikkie op, stuurt het naar je pagina (index.php) die meteen kan bepalen of de huidige user mag editen, die de template kan laden, de template kan doorgeven welke contentitems op welke plaatsen ingeladen moeten worden, etc. zonder opnieuw je database te hoeven aanspreken. Sterker nog, je kunt je hele dataobject ineens cachen (weet niet of dit voor PHP opgaat).


En tja, dat je daarbij misschien wat overbodige data ophaalt, who cares? Stel dat je gebruikmaakt van modules die hun eigen functionaliteit hebben en bepaalde informatie nodig kunnen hebben, dan kun je er daarbinnen altijd vanuitgaan dat je die data beschikbaar hebt.

[ Voor 13% gewijzigd door Not Pingu op 03-01-2006 13:07 ]

Certified smart block developer op de agile darkchain stack. PM voor info.


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Stukje van Michali: de code die jij gaf geeft bij mij een error
code:
1
Fatal error: Call to a member function on a non-object in /index.php on line 48


Nog bedankt voor je tijd Michali, een hele mooie post waar ik & anderen veel aan hebben.
de fout zit hier:
PHP:
1
2
3
4
    function getCurrentUser() {
        $user = UserRepository::getByUserIDAndSession($_COOKIE['userid'], $_COOKIE['session']);
        return is_null($user) ? new User() : $user;
    }


Volgens mij kan dit ook niet met PHP4 :) Zal eens kijken of een update naar PHP5 een optie is.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Nee, de fout zit hier in:
PHP:
1
return $this->createUserFromQuery($query);

moet zijn:
PHP:
1
return self::createUserFromQuery($query);


Zie ook het onderste voorbeeldje hier.

Ook in php5 geeft dat dezelfde error. Maar een update naar php5 is verder zeer zeker aan te raden.

[ Voor 17% gewijzigd door Michali op 03-01-2006 20:20 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
self is niet gedefinieerd in php4 iig.
Dus dat word updaten naar php5 ;)

Acties:
  • 0 Henk 'm!

  • mOrPhie
  • Registratie: September 2000
  • Laatst online: 09:26

mOrPhie

❤️❤️❤️❤️🤍

Self heb je alleen maar binnen de scope van de classe, nu moet je de naam van de classe gebruiken. Je probeert die functie statisch aan te roepen. Als getCurrentUser in UserManager staat, dan moet je dus ofwel
code:
1
UserManager::getCurrentUser()
aanroepen (er zou misschien "$" voor moeten, niet getest en ook geen mogelijkheid toe nu). Wat je ook kan doen is gewoon een UserManager instantieren, maar dat is lauter een design-issue. :)

Een experimentele community-site: https://technobabblenerdtalk.nl/. DM voor invite code.


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
RedHat schreef op woensdag 04 januari 2006 @ 06:44:
self is niet gedefinieerd in php4 iig.
Dus dat word updaten naar php5 ;)
De fout zat dus niet in het stukje code dat je gaf. Ik mijn code heb ik het ook gewijzigd. Het was regel 46, dat is nu een comment, regel 47 is nu de juiste. En omdat zowel de call als de functie definitie binnen de class UserRepository zitten kun je wel self:: gebruiken. De fout zit dus niet in getCurrentUser, die functie zit wel buiten de scope van UserRepository en dat moet wel gewoon UserRepository:: zijn.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Oke aangepast

Ik krijg te zien: Not logged in mate.
Dwz dat:
PHP:
1
2
3
    function isLoggedIn() {
        return isset($_COOKIE['session']) && $this->session == $_COOKIE['session'];
    }


niet goed is... ik denk dat het fout gaat na die && dus ik zet ze even onder elkaar om te testen.

PHP:
1
2
3
4
    function isLoggedIn() {
        $this->session == $_COOKIE['session'];
        return isset($_COOKIE['session']);
    }
werkt weer wel :)

Probleem is, dat hij 2 dingen doet, $this->session definieren en returnen of er een cookie aanwezig is, en dat mocht volgens mij niet helemaal :)

ValidUser() werkt nog niet, iemand nog tips?
Hij geeft is_null terug (dus hij word niet geset)

[ Voor 35% gewijzigd door RedHat op 04-01-2006 20:00 ]


Acties:
  • 0 Henk 'm!

  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 11-06 21:55
In het eerste code voorbeeld moet je nog even creatief met haakjes werken, of iig even op zoeken of == voor &&.

Wat je nu in het tweede stuk doet is imho nogal zinloos, die function isLoggedIn() doet nu eigenlijk maar 1 ding en dat is een boolean return of $_Cookie['session'] wel of niet bestaat. Met die vergelijking wordt nu helemaal niets meer gedaan, dat lijkt mij nou net niet helemaal de bedoeling.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Nu slaat je isLoggedIn functie alleen nergens op. Het eerste statement wordt namelijk gewoon compleet genegeerd. Hij wordt wel uitgevoerd, alleen wordt er niets met de waarde gedaan. (wat hierboven ook gezegd wordt dus ;)) De uitkomst is puur afhankelijk van wat je na de return zet. Probeer gewoon eens te dumpen (met var_dump bv.) wat de waarde van session in de cookie is en die van de class zelf. Dan ben je er snel achter. Je moet niet zomaar proberen een functie werkend te krijgen, zodat hij een check passeert, dat ik is niet echt veilig. Je moet gaan kijken waarom dat zo is. In dit geval is dat dan duidelijk, $this->session != $_COOKIE['session'], zo blijkt wel.

Wat bedoel je verder met validUser (isValid in mijn code) werkt niet? Bedoel je dat je een error krijgt, of passeert hij de check gewoon niet? In dat geval betekent het dat User::$userID geen waarde heeft gekregen, oftwel, UserManager heeft een lege user terug gegeven als current user. $_COOKIE['userid'] heeft dus als waarde een ID van een user die niet bestaat. Print in een aantal functies gewoon eens uit wat de waarde van de parameters zijn en wat er terug gegeven wordt. Dan kun je zien wat er gebeurt. Het is sowieso wel aan te raden om dat te leren, debuggen zul je veel moeten doen.

[ Voor 10% gewijzigd door Michali op 04-01-2006 22:33 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • RedHat
  • Registratie: Augustus 2000
  • Laatst online: 11-06 17:37
Dat hele oop is leuk als je het een beetje begint te snappen.

De code die ik nu heb:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php

class User {
    var $userID;
    var $username;
    var $session;
    
    function User($userID = null, $username = null, $session = null)
    {
        $this->userID = $userID;
        $this->username = $username;
        $this->session = $session;
    }
    
    function getUserID() {
        return $this->userID;
    }
    
    function getUsername() {
        return $this->username;
    }
    
    function getSession() {
        return $this->session;
    }
    
    function isLoggedIn() {
        $this->session = $_COOKIE['session'];
        return isset($_COOKIE['session']);
    }
    
    function isValid() {
        return !is_null($this->userID);
    }
}

class UserManager {
    function getCurrentUser() {
        $user = UserRepository::getByUserIDAndSession($_COOKIE['username'], $_COOKIE['session']);
        return is_null($user) ? new User() : $user;
    }
}

class UserRepository {
    function getByUserIDAndSession($username, $session) {
        $query = "SELECT * FROM Users WHERE userName = '" . $username . "' AND userSession = '" . $session . "'";
        return UserRepository::createUserFromQuery($query); 
    }
    function createUserFromQuery($query) {
        $result = mysql_query($query) or die(mysql_error());
        if (!( $record = mysql_fetch_assoc($result))) echo"whacked";
        return new User(
            $record['userID'],
            $record['userName'],
            $record['userSession']
        );
    }
    
    
    
}

$currentUser = UserManager::getCurrentUser();
if (!$currentUser->isLoggedIn()) die ("not logged in");
if (!$currentUser->isValid()) die ("n0t Val1d" . $currentUser->getUsername());
echo $currentUser->getUserName();

?>


Nu komt er nog een functie om bepaalde rechten voor een sectie te controleren.

De Query die ik gebruikte om rechten mee te fetchen, in het oude non-op educatief voorbeeldje, was dit (ipv de query om user te fetchen zoals hierboven)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
            $cLoginQ = "SELECT      Users.userName, 
                                    Users.userSession, 
                                    Users.userIsActive, 
                                    DATE_FORMAT(Users.userLastLogin, '%d-%m-%Y %H:%i:%s') as userLastLog, 
                                    Rights.rightUserID, 
                                    Rights.rightPageAccess, 
                                    Rights.rightPageCreate, 
                                    Rights.rightPageEdit, 
                                    Rights.rightPageRemove, 
                                    Rights.rightPageVisible, 
                                    Rights.rightUserAccess, 
                                    Rights.rightUserCreate, 
                                    Rights.rightUserEdit, 
                                    Rights.rightUserRemove, 
                                    Rights.rightEditAccess, 
                                    Rights.rightEditRights, 
                                    Rights.rightMailView, 
                                    Rights.rightMailRemove, 
                                    Rights.rightMailProcessed, 
                                    Rights.rightMailCreateNote, 
                                    Rights.rightMailRemoveNote, 
                                    Rights.rightMailEditNote,
                                    Rights.rightUploadAccess, 
                                    Rights.rightUploadFile, 
                                    Rights.rightUploadDelFile, 
                                    Rights.rightStatView, 
                                    Rights.rightStatSwap 
                        FROM 
                                    Users 
                        INNER JOIN 
                                    Rights 
                        ON          
                                    Rights.rightUserID = Users.userID
                        WHERE 
                                    userSession = '$_COOKIE[session]' 
                        AND 
                                    userName = '$_COOKIE[username]'";


Dit kan niet meer met OOP, want dan gaat een functie twéé dingen doen, en usergegevens ophalen en rechtengegevens ophalen.

Hoe kan ik dit het beste aanpakken (puur educatief dus, ik ga bovenstaande code uitbreiden zodat ik er verders nog wat van kan leren).

Er komt dus een functie om rechten te controleren. Alle rechten worden gefetcht, op een pagina word dus een user gevalideerd of hij/zij is ingelogt, en of alles klopt, dan worden de rechten opgevraagd (voorbeeld: getRights("canModifyUsers"); door die functie aan te roepen gaat ie kijken of hij canModifyUsers = 1 heeft gefetcht uit mysql.

iemand opvulling/aanvulling bovenstaande code?

Wat ik ook nog niet snap waarom 2 classes voor UserManagement en UserRepository?

[ Voor 12% gewijzigd door RedHat op 05-01-2006 08:12 ]


Acties:
  • 0 Henk 'm!

  • Not Pingu
  • Registratie: November 2001
  • Laatst online: 09-02 20:11

Not Pingu

Dumbass ex machina

RedHat schreef op donderdag 05 januari 2006 @ 08:10:

Dit kan niet meer met OOP, want dan gaat een functie twéé dingen doen, en usergegevens ophalen en rechtengegevens ophalen.

Hoe kan ik dit het beste aanpakken (puur educatief dus, ik ga bovenstaande code uitbreiden zodat ik er verders nog wat van kan leren).
Dit kan best met objecten. Zie ook mijn post hierboven. Ik weet niet precies in hoeverre OO in PHP is geimplementeerd, maar de rechten van een user zijn natuurlijk direct gerelateerd aan die user. Dus als je een User class hebt dan zou je rechtencollectie een property van die User class zijn.
Je kunt dan met die data uit die query een User object en de bijbehorende rechtencollectie ineens vullen en doorsturen naar de rest van je applicatie.

Certified smart block developer op de agile darkchain stack. PM voor info.


Acties:
  • 0 Henk 'm!

Anoniem: 3431

Heeft niet direct met OOP te maken, maar ik zou je databasemodel ook even aanpassen. Als ik je query lees heb je nu per recht een kolom. Als het goed is hoef je om een extra recht toe te voegen alleen een rij in te voegen in je rechtentabel

Ik gebruik drie tabellen: Rights, Users en UserRights (koppeltabel).

HTH.

edit:
ff wat duidelijker neergezet

[ Voor 30% gewijzigd door Anoniem: 3431 op 05-01-2006 10:04 ]


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Het kan zeker OO, maar het is gewoon een complex iets wat je wilt gaan doen. Om dit te implementeren heb je verschillende (lees: oneindig veel) mogelijkheden. Hoe je het doet is puur afhankelijk van wat je wilt en hoe het in je app past.

Een goede mogelijkheid is om de gehele rechten set bij het halen van de user uit de user repository op te halen en mee te geven aan de user.

Een andere mogelijkheid is om iets met lazy loading te gaan doen (al is dat denk ik iets te complex als je net met OO begint), dat houdt in feite in dat je de gegevens past inleest als je ze voor het eerst probeert te bereiken.

Nog een mogelijkheid is om een helper object (een Strategy, in Design Pattern taal) te maken (eentje die voor je user class controleert of hij een bepaalde recht heeft) en deze bij het instantieeren van je User object mee te geven. Je hoeft je User object dan alleen afhankelijk te maken van de interface van zo'n object (welke public functies hij heeft dus), maar je hoeft niet te weten hoe hij daadwerkelijk geimplementeerd is. Je kunt dan best een call naar de DB doen, als je die instantie maar niet door de User zelf aan laat maken. Dat moet dan door UserRepository gebeuren bijvoorbeeld.

Ik heb nu even geen tijd om een stukje code te tikken, straks wel denk ik, dus dan zal het wel iets duidelijker worden.

Edit: Toch een stukje geschreven:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php

// Domein

class User
{
    private $rights;
    
    public function __construct(IUserRights $rights)
    {
        $this->rights = $rights;
    }
    
    public function hasRightTo($action)
    {
        return $this->rights->hasRightTo($this, $action);
    }
}

interface IUserRights
{
    public function userHasRightTo(User $user, $action);
}

interface IUserRepository
{
    public function getByID($userID);
}

class Registry
{
    private static $userRepository;
    
    public static function setUserRepository(IUserRepository $userRepository)
    {
        self::$userRepository = $userRepository;
    }
    
    public static function getUserRepository()
    {
        return self::$userRepository;
    }
}


// Implementatie

class DBUserRights implements IUserRights 
{
    public function hasRightTo(User $user, $action)
    {
        $query = "
            SELECT r.`" . $action . "`
            FROM Rights r, User u
            WHERE r.rightUserID = u.userID
            AND u.userID = '" . mysql_real_escape_string($user->getUserID()) . "'
        ";
        $result = mysql_query($query);
        return 1 == (int)mysql_result($result, 0);
    }
}

class DBUserRepository implements IUserRepository 
{
    public function getByID($userID)
    {
        // select data met sql query op basis van $userID
        $user = new User(new DBUserRights());
        // user vullen met andere data
        return $user;
    }
}


// index.php (of waar je ook begint)

Registry::setUserRepository(new DBUserRepository());


// client code

$user = Registry::getUserRepository()->getByID(123);
if ( !$user->hasRightTo('editPages') ) die("Insufficient rights!");

?>


Het gaat me te ver om het allemaal uit te leggen. Ik denk dat het meeste wel voor zich spreekt. Het is zoals je ziet in PHP5 gemaakt. In php4 kan dit ook, alleen moet je dan die interfaces gewoon weghalen. Enkele patterns die ik heb gebruikt (mischien wil je daar wat over opzoeken):
Registry, Strategy, Depedency Injection/Inversion, Repository

Het is niet getest, het is ook geen complete implementatie. Het is gewoon om aan te geven hoe je zoiets kan oplossen. Het is al heel wat meer OO (en ook gelijk een stuk complexer) dan het vorige voorbeeld. Hopelijk kom je hier wat verder mee.

[ Voor 51% gewijzigd door Michali op 05-01-2006 13:49 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • TangLeFuzZ
  • Registratie: Juni 2001
  • Laatst online: 28-05-2024
Ik kwam dit topic tegen en vond sommige dingen vrij interessant, dus even een bump ;)

Michali; je zegt dat je het Repository pattern gebruikt in bovenstaande code.... ik heb daar zelf nog nooit van gehoord, en google geeft ook niet de juiste resultaten terug (als ik zoek naar repository kom ik juist allerlei code bases e.d. tegen ipv informatie over het pattern).

Heb je daar misschien wat meer uitleg over, of een link oid?

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 09:25
Mja, de vraag is of 'Repository' echt wel een pattern is, zoals je Observer / Strategy etc... hebt.

Een repository is eigenlijk een class waar je tegen spreekt, en die class is verantwoordelijk voor het ophalen/bewaren/etc... van een 'aggregate'. (Niet van een object van één class dus, maar van een object-graph).
Bv, een CustomerRepository kan een Customer incl. de Orders voor die customer ophalen (al dan niet mbhv lazy loading).

klik

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Repository is zeker geen design pattern, het is meer een domain pattern, en veel minder flexibel dan een dp en ook veel gerichter. Het idee is eigenlijk dat je een interface maakt welke functionaliteit bied voor het opslaan van een bepaald domein object, welke gebruikt wordt door andere domein objecten en eventueel door client code. Het fungeert eigenlijk als een soort speciale collectie, eentje die je ook methods geeft om objecten op basis van bepaalde criteria op te halen. Om het domein geheel afgescheiden te houden plaats je deze interface dan ook in de domein package, samen met de classes die hem gebruiken. Daarop gebaseerd kun je dan een implementatie leveren, bijvoorbeeld eentje die naar de DB schrijft, of in XML vorm. Hoe er opgeslagen wordt is natuurlijk niet relevant. (Je moet er natuurlijk wel een beetje rekening mee houden ivm. performance issues.)

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Waarom zorgt de User class zelf voor de authorisatie? Lijkt mij nou niet bepaald de taak van een User zelf zou ik dat in een Authorization class gezet hebben en de User in principe niet veel meer als een Value Object laten zijn (danwel iets in die trant).

Acties:
  • 0 Henk 'm!

Anoniem: 99283

PrisonerOfPain schreef op zaterdag 25 februari 2006 @ 15:25:
Waarom zorgt de User class zelf voor de authorisatie? Lijkt mij nou niet bepaald de taak van een User zelf zou ik dat in een Authorization class gezet hebben en de User in principe niet veel meer als een Value Object laten zijn (danwel iets in die trant).
Waarschijnlijk is de authorisatie een verantwoordelijkheid gemaakt van de User class, omdat dat de "information expert" is hier; een hoop informatie die benodigd is voor het authorisatie-proces is opgeslagen in de User class zelf.
Pagina: 1