PHP OOP - Property setten middels constructor of methode?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Top Low-Code Developer Gezocht!

Bedrijfsomschrijving Unieke Kansen, Uitstekende Arbeidsvoorwaarden & Inspirerend Team Wij zijn een toonaangevende, internationale organisatie die de toekomst van technologie vormgeeft door het creëren van innovatieve en baanbrekende oplossingen. Ons succes is gebaseerd op een hecht en gepassioneerd team van professionals die altijd streven naar het overtreffen van verwachtingen. Als jij deel wilt uitmaken van een dynamische, vooruitstrevende en inspirerende werkomgeving, dan is dit de perfecte kans voor jou! Functieomschrijving Als Low-Code Developer ben je een cruciaal onderdeel van ons team. Je werkt samen met collega's uit verschillende disciplines om geavanceerde applicaties te ontwikkelen en te optimaliseren met behulp van Low-code

Bekijk vacature »

Kevin de Groot

Kevin de Groot

28/01/2013 10:12:15
Quote Anchor link
Beste mensen,

Ik zit met een vraagje en ik kan hier niet echt een duidelijk antwoord op vinden. De antwoorden die ik vind, hebben weer te maken met andere zaken dan waar ik de vraag om stel.

Wanneer ik bijvoorbeeld een klasse 'Gebruiker' heb aangemaakt, kan ik dan beter property 'gebruiker_id' setten middels de klasse-constructor of middels een methode (bijv. 'set_gebruiker_id')?

Voor zover ik weet:

Voordelen methode 1 (middels de constructor):
- Je hoeft geen methode meer aan te roepen (in de constructor kun je deze property zonder methode vullen);
Note: ik zou sowieso een methode maken, mocht je van 'id' willen wisselen.

Voordelen methode 2 (middels een setter):
- Voor elke property kun je een setter en getter maken (lijkt me uiteindelijk overzichtelijker);
Note: in sommige gevallen (bijv. database-klasse) is een constructor misschien geschikter.

- Uiteindelijk wordt het dan voor grotere projecten gebruikt, dus wat is overzichtelijker?
- Zitten hier nog performance-verschillen in?

Dus: optie 1 of optie 2 van het onderstaande voorbeeld?

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php

// Methode 1 - middels de constructor

class Klassenaam1 {

    private $_id;
    
    public function __construct($id = 0)
    {

        $this->_id = intval($id);
    }

    
    public function get_id()
    {

        return $this->_id;
    }
    
}


$klassenaam1 = new Klassenaam1(1337);

echo $klassenaam1->get_id();

/* -------------------------- */

// Methode 2 - middels een methode


class Klassenaam2 {

    private $_id;
    
    public function set_id($id = 0)
    {

        $this->_id = intval($id);
    }

    
    public function get_id()
    {

        return $this->_id;
    }
    
}


$klassenaam2 = new Klassenaam2;
$klassenaam2->set_id(1337);

echo $klassenaam2->get_id();

?>


Alvast bedankt voor de tips/reacties! :-)

Gr. Kevin
 
PHP hulp

PHP hulp

24/11/2024 11:02:27
 
Erwin H

Erwin H

28/01/2013 10:22:21
Quote Anchor link
Ik zou een mix hiervan doen :-)

Je kan best via de constructor een waarde geven, niets mis mee. Alleen ook als je het in de constructor doet, zou ik het nog via een setter doen. Reden is heel simpel. Als je later nog eens een extra check wil invoeren (bijvoorbeeld id moet groter dan 0 zijn), dan hoef je alleen die setter aan te passen. Omdat de constructor ook die setter aanroept, ben je gelijk klaar.
 
Kevin de Groot

Kevin de Groot

28/01/2013 10:36:07
Quote Anchor link
Thanks voor jouw snelle reactie :-)

Ja, een combinatie van die twee leek me ook wel een geschikte optie. Als ik voor methode 1 zou gaan, dan zou ik sowieso ook een set-methode aanmaken (om de duidelijke reden die jij ook noemde).

Maar tijdens de eerste init (of hoe je dat ook noemt) van de klasse, kan dit beter/netter middels de constructor (enkel en alleen het id), of niet? Mocht ik later het id willen veranderen, dan kan dat middels de setter.

Ik heb nog even rondgekeken en wat ik zo kon vinden over de performance: het zou niets uit moeten maken. Zelfs bij aardig grote projecten is dit verschil nihil.

Ik ben dan van plan om het zo te gaan oppakken:

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

$gebruiker
= new Gebruiker(1337); // 1337 komt uit een GET-waarde
$gebruiker->load(); // Deze methode haalt de gegevens uit de database o.b.v. het id en set de properties direct (niet met de methodes).

echo $gebruiker->get_gebruiker_id(); // Output: 1337

// Mocht je van id willen wisselen, dan kan dat met deze setter:

$gebruiker->set_gebruiker_id(666);

echo $gebruiker->get_gebruiker_id() // Output: 666

?>


Enige nadeel van deze methode (i.c.m. de load-methode) is dat bij het aanroepen van load(), dat er dan een hoop "overbodige/extra" gegevens worden geladen.
 
Erwin H

Erwin H

28/01/2013 10:42:46
Quote Anchor link
Wat ik al zeg, prima om het via de constructor te doen, maar dan dus wel zo:
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
<?php
class Klassenaam1 {

    private $_id;
    
    public function __construct($id = 0)
    {

        $this->set_id( $id );
    }

    
    public function set_id($id = 0)
    {

        $this->_id = intval($id);
    }

    
    public function get_id()
    {

        return $this->_id;
    }
    
}


?>

Wat betreft die load functie, daar kan je dus ook een property in je class bouwen die bijhoudt welke gegevens moeten worden opgehaald. Daar zet je standaard waardes in via de constructor, maar kan je laten veranderen middels een setter. Heeft een bepaalde pagina dus veel minder gegevens nodig dan kan dat worden aangepast.
Gewijzigd op 28/01/2013 10:44:06 door Erwin H
 
Kris Peeters

Kris Peeters

28/01/2013 10:50:54
Quote Anchor link
Kevin de Groot op 28/01/2013 10:36:07:
... Maar tijdens de eerste init ... kan dit beter/netter middels de constructor (enkel en alleen het id), of niet?..


Die vraag kan teruggekaatst worden.

Heb jij tijdens de constructor die waarde al nodig?
Indien niet, kan het later gebeuren.


Een voorbeeld: pdo.
$db = new PDO($dsn, $user, $password);
Hier vind ik het vrij relevant dat de connectie-gegevens al bij de constructor worden meegegeven.
Na het aanroepen van de constructor is het object klaar voor gebruik.

Andere "optionele" settings kunnen beter later.
bv.
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
 
Kevin de Groot

Kevin de Groot

28/01/2013 11:07:25
Quote Anchor link
Oké, als ik het goed begrijp moedig je me juist aan om in de constructor de property juist wél te setten middels de methode? Klinkt ook wel logisch, eigenlijk, want dant dan kun je in die methode gewoon de waarde ervan valideren (bijv. de simpele intval).

En wat betreft de load-functie: een extra parameter (een array bijvoorbeeld) meesturen naar de constructor. En dan in de load-methode die gegevens uit de array halen? Bijvoorbeeld (en let niet op gegevens-validatie, het gaat om het idee):

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
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
<?php

class Klassenaam {
    private $_gebruiker_id;
    private $_gegevens;

    public function __construct($gebruiker_id = 0, $gegevens = array())
    {

        if (!is_array($gegevens))
        {

            $gegevens = array('gebruikersnaam', 'email');
        }

        
        $this->set_gegevens($gegevens);
        $this->set_gebruiker_id($gebruiker_id);
    }

    
    public function set_gegevens($gegevens = array())
    {

        unset($this->_gegevens);
        
        $this->_gegevens = $gegevens
    }
    
    public function set_gebruiker_id($gebruiker_id = 0)
    {

        $this->_gebruiker_id = intval($gebruiker_id);
    }

    
    public function get($veld = 'id')
    {

        if (in_array($veld, $this->_gegevens))
        {

            return $this->_gegevens[$veld];
        }

        else
        {
            return 'niet bekend';
        }
    }

    
    public function load()
    {

        $query = "SELECT ". implode(',', $this->_gegevens) ." FROM gebruiker WHERE gebruiker.id = ". $this->_gegevens ." LIMIT 1";
        
        // De rest van de code (fetchen enz)...
        
        foreach($this->_gegevens as $i => $veld)
        {

            $this->_gegevens[$veld] = $fetch[$veld];
        }
    }
}


$gebruiker = new Gebruiker(1337, array('gebruikersnaam', 'email', 'wachtwoord'));

$gebruiker->load();

?>


Zo kun je die array met gegevens ook aanroepen in de load-methode, maar goed, het gaat om het idee :-)

Ik heb enkele simpele systeempjes gemaakt in OOP, maar het is allemaal te omslachtig. Voor elke property twee methodes (set en get) aanmaken met allemaal statische/hard-coded benamingen. Wat ik wil zeggen is: ik ben niet geheel nieuw in OOP, wel in praktische/dynamische zaken. Als hier tutorials over te vinden zijn, dan lees ik die met alle plezier doen :-) Een cursus kan ik niet van jou/jullie vragen, haha!

Toevoeging op 28/01/2013 11:10:24:

Oeps, ik had jouw bericht over het hoofd gezien, Kris.

Gegevens m.b.t. de verbinding met de database vind ik wel logisch om die mee te geven in de constructor. In dit geval (gebruiker-klasse) vind ik een gebruiker_id meesturen ook wel relevant. Op basis van een gebruiker_id kan er van alles gedaan worden, gebruiker_id is in dit geval vereist. Zo kun je andere methodes gebruiken voor handelingen met deze gebruiker(_id).
 
Erwin H

Erwin H

28/01/2013 11:15:40
Quote Anchor link
Het idee klopt inderdaad. Afgezien van de validatie denk ik alleen dat je 1 fout maakt. Eerst plaats je de op te halen kolommen in $this->_gegevens, later plaats je de opgehaalde gegevens in $this->_gegevens. Als je dus na de load method nog een keer de set_gegevens method aanroept dan ben je al je gebruikers gegevens weer kwijt. Lijkt mij handiger om dat in twee verschillende properties op te slaan.
 
Kevin de Groot

Kevin de Groot

28/01/2013 12:02:36
Quote Anchor link
Ah, inderdaad! Dat heb ik over het hoofd gezien ;-)

Dus drie properties aanmaken (in dit voorbeeld):

1. gebruiker_id (bijvoorbeeld: 1337)
2. velden (bijvoorbeeld: array('voornaam', 'achternaam'))
3. waarden (bijvoorbeeld: array('Kevin', 'de Groot'))

Misschien niet overal de juiste namen gebruikt, maar het is een voorbeeldje.
 
Erwin H

Erwin H

28/01/2013 12:04:27
Quote Anchor link
Precies.
 
Kevin de Groot

Kevin de Groot

28/01/2013 12:17:23
Quote Anchor link
Thanks! :-)
 



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.