Nu heb ik verzonnen dat ik een class 'core' heb die dingen afhandeld als berichtgeving naar de gebruiker, of debug info etc.
om nu gebruik te kunnen maken van de functions in 'core' laat ik iedere andere class 'core' extenden, maar nu komt het: hoe zorg ik er voor dat alle extendende classes dezelfde instantie van 'core' gebruiken zodat alle berichten bij elkaar uitkomen?
ik zat te denken aan singleton, maar ik heb gelezen dat dit meestal niet nodig is en anders toch wel geen idee is ivm beperkingen die dan optreden.
of is er nog een andere (betere) optie?
bij voorbaat alvast denk voor het lezen van m'n vraag
Ivar
PS als je iets niet snapt aan mijn vraag vraag het dan, dan kan ik het uitleggen!
Een sessie is bedoelt om gegevens tussen de verschillende request van een user te delen niet omzomaar alles op te slaan wat je tijdens een request nodig hebt.
Door keuzes te maken met behulp van de design patterns zoals singleton en registry kun je een nette opzet maken voor je applicatie.
ik zou graag die posts weg hebben maar ik kan deze zelf niet verwijderen.
ik wil hier dan ook gelijk aan toevoegen dat ik dit een zeer vervelende bug vind.
@han dit is hier idd beter geschikt voor.
edit: bedankt voor het verwijderen van de posts edit 2: ik gebruik nu dit in de 'core' class:
public function __construct()
{
$GLOBALS[__CLASS__] = $this;
}
en dan kan ik overal deze class aanroepen dmv:
$GLOBALS['Core']->addMsg('HELLO WORLD');
dit werkt, maar als iemand nog een tip heeft om deze methode te verbeteren hoor ik het graag! ik zou eventueel ook de berichten array in een $GLOBALS kunnen zetten, maar ik denk dat dit handiger is :P
Wat je nu doet is eigenlijk singleton implementeren, maar dan op zo'n manier dat het niet echt werkt :)
Probleem 1: Je verbindt $GLOBALS['Core'] onlosmakelijk met die ene klasse. Bij een normale singleton implementatie heb je tenminste nog de vrijheid te kiezen welke klasse je aanroept, en bij een registery heb je nog de vrijheid welk object je onder een bepaalde naam in het registery stopt. Dit is in één applicatie niet zo'n probleem, maar zodra je de code wilt hergebruiken is er een redelijke kans dat dit je in de weg gaat zitten.
Probleem 2: Wanneer je nu een nieuwe instantie van Core aanmaakt, overschrijft hij de oude in $GLOBALS['Core']. Alle berichten die in de oude zaten zijn dan foetsie, tenzij je nog een andere referentie had naar die ene oude instantie. Maar dat zou betekenen dat je meerdere instanties van hetzelfde object hebt, wat weer het voordeel van singleton, of een globale message-passer wegneemt.
Probleem 3: $GLOBALS is vrij te veranderen. Wanneer jij eerst de instantie van Core start, en daarna toevallig in een lusje of ergens anders ogenschijnlijk onschuldig een variabele genaamd $core binnen de global scope gebruikt (en die is groot in PHP) is je Core instantie foetsie. Dat is soms best lastig te debuggen, en je moet je best doen goeie variabele-namen te verzinnen die elkaar niet in de weg zitten. Daarom sla je bij Singleton de instantie op in de klasse zelf, zodat het onmogelijk om vanuit de rest van je code bij deze instantie te komen. De klasse heeft volledige controle. (En dat is goed :) )
Ik kan je aanraden je klassen altijd zo autonoom mogelijk te maken. Van zo min mogelijk andere klassen afhankelijk, het liefst van geen enkele gobale variabele afhankelijk, en als je hem toch afhankelijk wilt maken van andere klassen (wel zo handig in veel gevallen, scheelt dingen dubbel implementeren en dubbel fixen) doe dat dan weer zo veel mogelijk via methods, zodat je niet tijdens het bedenken van de klasse beslist welke andere klassen zijn benodigdheden gaan geven (zoals databases) maar maak een method zodat je de database aan de instantie kan koppelen. Op die manier hoef je pas bij het gebruik van de klasse te beslissen hoe je de database gaat aanleveren.
<?php
class Teletubbie {
protected $_database;
public function __construct() {
/* Nu kan je niet om het gebruik van Database heen */
$this->_database = new Database();
}
}
class Teletubbie {
protected $_database;
public function __construct($database) {
/* Het enige waar je je nu nog zorgen over hoeft te maken is of je
* $database wel kan wat jij hoopt hij kan. Maar daar kan je
* Interfaces (op PHPfreakz staat een goed artikel daarover)
* voor gebruiken. */
$this->_database = $database;
}
}
$database = new SuperDuperTurboDatabase(); // véél beter dan de normale Database ;)
$teletubbie = new Teletubbie($database);
?>