Class in een class
Ruben Portier op 24/12/2012 13:51:50:
Hier begin je dus al verkeerd. In een echte OOP omgeving is er maar 1 object dat je in de global space (je index file) aanmaakt en dat is de controller of het application object (afhankelijk van welk pattern je gebruikt). De hele afhandeling van het request wordt vervolgens in dat object afgewerkt. Alle andere objecten die worden aangemaakt worden danook vanuit dat ene object geinitieerd.
Ja, zo heb ik het toch ook. Of begrijp ik je hier verkeert? Dit hele topic gaat er net over dat ik maar één object wil aanmaken voor bijvoorbeeld de database. Daarom stuur ik het $db object door naar bijvoorbeeld de user class zodat ik die kan hergebruiken i.p.v. een nieuwe aan te maken.
Ik denk dat je mijn opmerking niet begrijpt. He gaat er niet om hoeveel database objecten je aanmaakt, maar om waar je die aanmaakt. Zoals gezegd, in een echte OOP omgeving zal je dat niet in je index file doen. Daar maak je namelijk alleen het applicatie object aan, verder niets. Een db object maak je normaal gesproken binnen een factory of een service container aan.
Oke, bedankt! Ik begrijp het nu. Dus ik mag eigenlijk geen database object aanmaken zolang ik deze niet nodig heb. Dus dan moet ik telkens als ik de database nodig heb het volgende doen: $db = new mysql($host,$password..); Als ik dan klaar ben doe ik $db->closeConnection of zoiets? Bedankt alvast!
Wat de juiste OO methode is:"
Code (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
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
<?php
// kernel.php
/**
* De kern van je applicatie
*/
class Kernel
{
private $database;
/**
* Deze functie wordt aangeroepen en handelt een pagina request af.
*/
public function handle(...)
{
$db = $this->getDatabase();
// ... andere code die alles gaat afhandelen
}
protected function getDatabase()
{
if (null === $this->database) {
$this->setDatabase();
}
return $this->database;
}
protected function setDatabase()
{
$this->database = new Database(...);
}
}
?>
<?php
// bootstrap.php
require_once 'kernel.php';
?>
<?php
// index.php
require_once 'bootstrap.php';
$kernel = new Kernel();
$kernel->handle();
//! niet meer
?>
// kernel.php
/**
* De kern van je applicatie
*/
class Kernel
{
private $database;
/**
* Deze functie wordt aangeroepen en handelt een pagina request af.
*/
public function handle(...)
{
$db = $this->getDatabase();
// ... andere code die alles gaat afhandelen
}
protected function getDatabase()
{
if (null === $this->database) {
$this->setDatabase();
}
return $this->database;
}
protected function setDatabase()
{
$this->database = new Database(...);
}
}
?>
<?php
// bootstrap.php
require_once 'kernel.php';
?>
<?php
// index.php
require_once 'bootstrap.php';
$kernel = new Kernel();
$kernel->handle();
//! niet meer
?>
Ik snap het nog niet helemaal. Dus ik mag geen global $db aanmaken? Dus ik moet pas een object aanmaken in de classes zelf? Maar dan zit ik met het probleem dat ik na een tijdje meer dan 10 verschillende database objecten (database connecties) heb en dat bevorderd de performance van de website zeker niet.
Dat is wat Wouter hier doet:
Code (php)
Als $this->database null is (ergo, er bestaat nog geen database object) dan maakt hij er 1 aan en geeft die terug. Bestaat er wel al 1 dan geeft hij die direct terug.
Wat je nu in de rest van je classes moet doen, is altijd deze functie aanroepen in dit object en dus niet elke class zijn eigen database object laten aanmaken.
Dit komt bovenin de index file:
Dit komt dan in een class:
Code (php)
Maar dan zit ik weer met de vraag, hoe kom ik in die user class aan de $classes class?
EDIT: Na het even beter bekeken te hebben is bovenstaande niet echt een antwoord op mijn vraag. Volgens mij moet ik dus gewoon alle regels waar ik een nieuw object aanmaak uit mijn index halen en dat in een class regelen. Dat is inderdaad iets waarvoor OO bekend staat. Maar dat is niet echt een antwoord op mijn vraag. Want dan moet de kernel class alsnog de $this->database meegeven aan de user class. Dus dat was niet echt mijn vraag
Ik wil weten of het mogelijk is om de user class aan de database class te laten komen zonder dat ik deze hoef mee te sturen en zonder een nieuw object hiervoor aan te maken indien deze al bestaat (buiten de user class aangemaakt).
Gewijzigd op 26/12/2012 14:33:18 door Ruben Portier
Ruben Portier op 26/12/2012 14:06:05:
Ik wil weten of het mogelijk is om de user class aan de database class te laten komen zonder dat ik deze hoef mee te sturen en zonder een nieuw object hiervoor aan te maken indien deze al bestaat (buiten de user class aangemaakt).
Nee, ze komen niet uit de lucht vallen. Je zal altijd op de een of andere manier een object (referentie) moeten doorgeven van het ene object naar het andere.
Wat mij betreft zijn er drie mogelijkheden:
- meegeven in de constructor als het een absolute noodzakelijkheid is (denk aan een database configuratie in een database object)
- meegeven via een setter
- opvragen via een getter
De enige ander manier is dat je met globals gaat werken, maar dat is natuurlijk vloeken in de kerk als je in een OOP omgeving bezig bent.
Erwin H op 26/12/2012 15:34:35:
Nee, ze komen niet uit de lucht vallen. Je zal altijd op de een of andere manier een object (referentie) moeten doorgeven van het ene object naar het andere.
Wat mij betreft zijn er drie mogelijkheden:
- meegeven in de constructor als het een absolute noodzakelijkheid is (denk aan een database configuratie in een database object)
- meegeven via een setter
- opvragen via een getter
De enige ander manier is dat je met globals gaat werken, maar dat is natuurlijk vloeken in de kerk als je in een OOP omgeving bezig bent.
Ruben Portier op 26/12/2012 14:06:05:
Ik wil weten of het mogelijk is om de user class aan de database class te laten komen zonder dat ik deze hoef mee te sturen en zonder een nieuw object hiervoor aan te maken indien deze al bestaat (buiten de user class aangemaakt).
Nee, ze komen niet uit de lucht vallen. Je zal altijd op de een of andere manier een object (referentie) moeten doorgeven van het ene object naar het andere.
Wat mij betreft zijn er drie mogelijkheden:
- meegeven in de constructor als het een absolute noodzakelijkheid is (denk aan een database configuratie in een database object)
- meegeven via een setter
- opvragen via een getter
De enige ander manier is dat je met globals gaat werken, maar dat is natuurlijk vloeken in de kerk als je in een OOP omgeving bezig bent.
Bedankt, maar zoals ik het hier nu ook even lees is het niet verstandig om via de contructor van een class alles in te stellen? Dus mijn databaseconfiguratie mag ik ook niet doorsturen aan de new mysql class? Dus ik moet eerst doen $db = new mysql(); en dan $db->set($host, $user...)?
Bedankt alvast!
Voor je user class, die user class kan vast ook nog wel dingen zonder dat er een database connectie is. Het meegeven van het database object in de constructor is dan dus geen noodzaak en dus geen goed idee.
Bedenk dat als je een object mee moet geven in de constructor, je die class niet meer kunt aanmaken als dat mee te geven object niet beschikbaar is. Als je dus iets kan zonder dat object, is het verstandig die afhankelijkheid niet te sterk te maken.
Gewijzigd op 26/12/2012 19:23:30 door Ger van Steenderen
Voorbeeld:
Ik denk dat dit gewoon de meest simpele en veilige manier is. Je geeft alleen het object mee als je dat wil.
Nogmaals heel erg bedankt aan iedereen die me geholpen heeft!