[OOP] Implementeren admin functie

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Wim E

Wim E

16/05/2012 08:30:45
Quote Anchor link
Beste allemaal,

Ik wil graag even sparren over een probleem.
Ik heb 3 klassen. Person, User en Admin.

Person is abstract
User en Admin overerven Person.

Op moment dat ik inlog wil ik op 1 of andere manier dat de klassen Person (de klasse met de constructor) zelf bepaald of het een User of een Admin is.
Een gebruiker moet in dit geval enkel de User functionaliteit hebben.
Maar de beheerder de Admin functionaliteit.

De klasse Person bevat alle persoonsgegevens + username, access level

Kortom, hoe kan ik het voor elkaar krijgen dat wanneer ik enkel een gebruiker id heb een nieuwe instantie aanmaak en deze zelf bepaald of hij een User is of dat het een Admin is?
 
PHP hulp

PHP hulp

24/11/2024 19:58:48
 
Chris PHP

Chris PHP

16/05/2012 08:36:23
Quote Anchor link
Dat kun je dan toch gewoon met een if statement doen, of met een switch?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
if ($person->level == 11) {
// voer script en/of doorverwijzing uit als het acces level 11(gebruiker) is
} else if ($person->level == 44) {
// voer script en/of doorverwijzing uit als het acces level 44(admin) is
} else {
// voer script en/of doorverwijzing uit als het acces level leeg is (gast)
}
?>


Uiteraard kun je alles gebruiken voor het bepalen van de access leves, dit is slechts een voorbeeld. Ik neem aan dat je deze gegevens in een DB hebt staan? Dus de gebruikers/admins zullen een veld access_level of iets dergelijks hebben?

En om bepaalde pagina's te beperken tot admin kun je het access level ook toevoegen aan een sessie. En dan vervolgens zoiets gebruiken per pagina.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
session_start();


if (isset($_SESSION['alevel']) $$ $_SESSION['alevel'] == 44) {
//Laad admin pagina hier
} else { header ("Location: onbevoegd.php"); }
?>
Gewijzigd op 16/05/2012 08:41:38 door Chris PHP
 
Wim E

Wim E

16/05/2012 13:26:52
Quote Anchor link
Hoi Chris,

Ja dat kan ik inderdaad doen. Maar probeer wel het SOLID principe aan te houden..
Daarnaast niet echt OOP om met if else te gaan bepalen wat voor object je moet aanmaken...

Met andere woorden, ik wil eigenlijk gewoon een user id meegeven en de klasse zelf laten uitzoeken of hij een Admin is of een User...

Wellicht moet ik met een Interface werken...
 
Chris PHP

Chris PHP

16/05/2012 13:30:41
Quote Anchor link
Waarom wil je dat je met OOP doen? Waarom haal je niet gewoon je access level
waarde uit de database en zet je dit in een sessie? Dat is sneller en makkelijker.
 
Erwin H

Erwin H

16/05/2012 13:47:22
Quote Anchor link
Een conditioneel statement blijf je natuurlijk altijd ergens houden. Je hebt een keuze namelijk.

Maar wat je in eerste instantie vraagt lijkt me een beetje onmogelijk. Als de klasse Person abstract is, dan kan die niet bepalen welke child-klasse aangemaakt gaat worden. Volgens mij kan dat uberhaupt niet, een geovererfde klasse laten bepalen welke child-klasse geinstantieerd wordt.

Wat je wel zou kunnen doen, is de verschillen tussen User en Admin entiteiten in apparte klassen opvangen en niet in children van Person. In die klassen bepaal je bijvoorbeeld of acties mogen worden uitgevoerd en of bepaalde data beschikbaar is. In de klasse Person neem je dat object op als een variabele. Volgens mij is dit een beetje het Dependency Injection principe (hoewel ik daar geen expert in ben).
Bij het instantieren van Person bepaalt Person (of een factory die Person aanmaakt) welke klasse wordt meegegeven en dus welke functionaliteit beschikbaar is. Als beide User en Admin klasse dezelfde Interface delen dan hoef je verder binnen Person nooit meer met conditionele statements te werken, dat wordt geregeld door welke klasse is meegegeven.
 
De VeeWee

de VeeWee

16/05/2012 13:48:55
Quote Anchor link
Kijk even naar het Factory design pattern:
http://en.wikipedia.org/wiki/Factory_method_pattern

Kort samengevat:
Je maakt een Factory klasse.
Hier neem je dan bijvoorbeeld een statische create functie met als parameter uw access level. In die create functie ga je dan zien welk object je moet bouwen. User of Admin.
Je krijgt dus altijd een instantie van Person terug.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
class Person_Factory
{

/**
 * @return Person
 */

public static function create($accessLevel)
{

switch ($accessLevel) {
   case
'x':
       return new User();
       break;
    case
'y':
       return new Admin();
       break;
    default:

       throw new Exception('invalid accesslevel');
}

}

}



$person = Person_Factory::create('x');
?>
Gewijzigd op 16/05/2012 13:57:10 door de VeeWee
 
Chris PHP

Chris PHP

16/05/2012 14:04:37
Quote Anchor link
@VeeWee,

En hoe komt x of y aan de waarde wat de gebruiker nu is?
En hoe gebruik je dit dan verder in de site om te kijken welke pagina voor welke gebruiker te benaderen is?

Ik ben net bezig met OOP, dus ben daar wel benieuwt naar.
 
De VeeWee

de VeeWee

16/05/2012 14:11:11
Quote Anchor link
Ok, ik ben iets te snel door ge bocht gegaan.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

// haal gegevens op uit database:
$tbl = new Table_Persons();
$data = $tbl->getByCredentials($email, $password);

// haal het object op:
// let op: die $data is nu een array of object geworden met een rij uit de database
// zie verder onderaan

$person = Person_Factory::create($data);

// hoe weten welke gebruiker het is?
$isAdmin = ($person instanceof Admin);
$isAdmin = $person->isAdmin();
// natuurlijk idem voor gebruiker
// die isX functie moet dan in het Person object zitten



?>


Create functie:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
/**
 * @return Person
 */

public static function create($data)
{


// create object
switch ($data['accessLevel']) {
   case
'x':
       $person = new User();
       break;
    case
'y':
       $person = new Admin();
       break;
    default:

       throw new Exception('invalid accesslevel');
}


// add data
// hier kan je eventueel ook een mapper klasse voor gebruiken

$person->setId($data['id']);
// ....


return $person;

}

?>
Gewijzigd op 16/05/2012 14:14:01 door de VeeWee
 
Erwin H

Erwin H

16/05/2012 15:09:08
Quote Anchor link
Ik bent het grotendeels met je voorbeeld eens, alleen dit zou ik niet doen:
De VeeWee op 16/05/2012 14:11:11:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$isAdmin
= $person->isAdmin();
// natuurlijk idem voor gebruiker
// die isX functie moet dan in het Person object zitten

?>

Dit betekent dat gebruik van het object afhankelijk wordt van de klasse. Wat je eigenlijk wilt, is dat je zowel User als Admin kan gebruiken zonder dat je hoeft te weten wat voor klasse het precies is. Met andere woorden, je krijgt van de factory een object terug wat alles kan wat je wilt doen, zonder je verder zorgen te hoeven maken over implementatie. Als je nu klasse specifieke methodes gaat implementeren dan werkt dat niet meer.
Als je al zoiets nodig hebt, dan zou ik een algemene methode in de interface definieren (iets als 'whatAmI') die dan een string of integer teruggeeft die aangeeft wat het object is. Op die manier blijft de aanroep hetzelfde, onafhankelijk van welke klasse is geinstantieerd.
 
Roy sterretje

Roy sterretje

16/05/2012 15:13:09
Quote Anchor link
In de sql database een rechten kolom aanmaken. en vervolgens op dat resultaat gaan kijken in een tabel rechten_functie daar staat dan het rechten nummer + de functie maar je blijft een if else houden. Wanneer je veel functies hebt is dit erg handig.
 
De VeeWee

de VeeWee

16/05/2012 15:25:06
Quote Anchor link
Erwin,

Over die isX() heb je wel gelijk. Maar overerving wordt ook gebruikt om extra functionaliteit in de klasse te plaatsen. Je moet er wel van uit gaan dat je in de rest van je project wel weet over welk type gebruiker het gaat. Uw admin object zal andere dingen kunnen doen als uw user object... Je moet het dus ook niet TE abstract bekijken. Maar ok, dat hangt dan natuurlijk ook weer af van wat je juist wilt bereiken natuurlijk.

Maar je hebt gelijk, de isX() functies gebruik ik normaal ook enkel voor een bepaald veld in de database. Bijvoorbeeld: isActive(), isDeleted(). instanceof zal dus in dit geval wel beter zijn.
 
Wim E

Wim E

16/05/2012 15:39:53
Quote Anchor link
Dag VeeWee,

Bedankt voor je antwoord.
Ik kan me zeker vinden in het factory pattern. Had niet stilgestaan om dit gebruiken.

Wat betreft depencency injection. (Interface verwachten) waarop je bepaalde methodes aanroept die in de interface zitten.

Afbeelding
 
Erwin H

Erwin H

16/05/2012 15:41:22
Quote Anchor link
Klopt, als je echt volkomen verschillende functionaliteit inbouwt dan krijg je snel natuurlijk verschillende functies die de een wel heeft en de ander niet. Als je echter de klasses gebruikt als een soort proxy, dus dat aan de hand van welke klasse is geinstantieerd wordt bepaald of bepaalde data beschikbaar is, dan wil je juist wel dat beide klasses gelijk blijven qua interface en dus dat je geen verschillende functies hebt in de verschillende klasses.

Welke hier wordt gebruikt is niet duidelijk, dus is het een ontwerp keuze hoe je het doet. Eens.

Toevoeging op 16/05/2012 15:48:01:

@Wim
Precies, volgens mij is dat een goed pattern voor het ontwerp waar jij mee zit. Tenzij je enorm veel extra functionaliteit in een van beide wilt hebben. In dat geval zou ik dus User en Admin geen kinderen laten zijn van Person.
 
Wouter J

Wouter J

17/05/2012 18:35:46
Quote Anchor link
Wat meer informatie + extreem goede uitleg over het Strategy Pattern (hetgeen wim gebruikt): http://www.lannoo.com/Media/extradownloads/9789077442715_Hoofdstuk%201.pdf
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.