request class
Ik ben een Request class aan het maken. Via deze class kan ik bijv. het domein van de opgevraagde URL opvragen, of het subdomein, en of het een beveiligde (https) verbinding betreft. De gegevens haal ik op uit de $_SERVER array. Nu had ik gewoon allemaal public funtcions gemaakt. Echter... ik realiseer me ineens dat gedurende 1 request de $_SERVER array altijd hetzelfde is. Het zou dan raar zijn als ik telkens als ik de Request class nodig heb "new Request()" zou doen.
Nu vraag ik me af wat volgens jullie de beste oplossing is. Ik zou een singleton kunnen maken, zodat je niet "$request = new Request()" doet, maar "$request = Request::getInstance()". Wat ik ook kan doen is iedere functie in de Request class static maken, zodat ik het domein bijv. als volgt opvraag: $domain = Request::getDomain();
Wat vinden jullie? En waarom?
Ik zou heel heel heel voorzichtig zijn met het gebruik van static methodes en naast een static factory method zou ik het nooit gebruiken. Je bent er nooit zeker van dat iets maar 1 keer gebruikt wordt.
Wat ik wel zou doen is de request opslaan als een shared service in je service container.
Gewijzigd op 03/01/2013 22:36:01 door Wouter J
Wouter, hoe bedoel je dat? Als je een pagina aanroept, dan heb je toch altijd maar 1 $_SERVER array... één request? Wat bedoel je met subrequests?
docs).
Iets compleet uitsluiten om maar 1 instance te hebben is naar mijn mening dus het stomste wat je kunt doen in een OO applicatie.
Subrequests zijn een request binnen een request. Symfony2 heeft bijv. een forward methode, hiermee kun je intern de ene controller naar de andere forwarden zonder dat de gebruiker er iets van merkt (Iets compleet uitsluiten om maar 1 instance te hebben is naar mijn mening dus het stomste wat je kunt doen in een OO applicatie.
Maar in mijn geval gaat het dus om een request class... je hebt maar 1 request per pagina aanroep. Dan kan je in dit specifieke geval toch een singleton gebruiken?
Quote:
dezelfde $_SERVER array?
Volgens PHP wel, alleen als je een Request object gebruikt verdwijnt het idee van die PHP array, de Request klasse vervangt dat compleet.
In een subrequest wordt er weer een nieuwe request aangemaakt, andere parameters, andere locatie, ect.
Op het moment dat jij daadwerkelijk een nieuwe (sub)request maakt, zal de class ook weer opnieuw worden ingeladen. Ik zie het probleem dus niet helemaal, maar wellicht zie ik iets over het hoofd nu, of begrijp ik je niet helemaal.
Het probleem van een singleton is dat je nooit een nieuwe instance kan krijgen in dezelfde request, je blokkeert op die manier dus alle mogelijkheden tot uitbreiding.
Nu snap je het misschien nog niet, maar straks misschien wel en dan moet je alles weer gaan veranderen omdat je het nu zo strikt in een tunnelvisie hebt geprogrammeerd. Het is nooit goed de weg naar de toekomst te blokkeren met zoiets als singletons.
Singleton is een zogenaamd anti-pattern. Ze lijken leuk en voor beginners zijn ze leuk, maar als je serieus bezig gaat moet je ze vermijden.
Offtopic:
Leuk dat je weer aan je framework begonnen bent, heb ik ook weer een discussie maatje :)
"Het probleem van een singleton is dat je nooit een nieuwe instance kan krijgen in dezelfde request"
Nee precies, maar dat is voor die request class ook precies wat ik wil bereiken ;)
Offtopic:
Yep, deze keer zelfs op een eigen (gehuurde) VPS. Hoop dat ik deze keer een stuk verder ga komen dan voorgaande keren ;)
Quote:
Waar zou ik die in de praktijk voor nodig kunnen hebben?
Bij het afhandelen van forms. Het form wordt verzonden, je controleert of alles correct is ingevuld, slaat de gegevens op en forward je dan naar een controller die de succes message laat zien. Een forward is een redirect die je intern gebruikt, je gebruikt hem dus waar het voor de bezoeker niks uitmaakt, hij hoeft geen nieuwe url te hebben voor de succes message.
Quote:
Nee precies, maar dat is voor die request class ook precies wat ik wil bereiken ;)
Ja, dat denk je en het is misschien ook wel zo, maar in OO moet je alle mogelijkheden open houden.
Ook als je unit of functional tests gaat schrijven heb je ook per test een nieuwe class nodig, niet per request. Een artikel daarover van PHP unit test god Sebastian Bregmann: http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html
Oké, maar dan is het nog steeds dezelfde request, maar je include een bestand. Is dat wat je bedoelt met forwarden? Of bedoel je dat je daadwerkelijk redirect naar een andere URL om de succes message te tonen? Als dat is wat je bedoelt, doe je dus feitelijk weer een nieuwe request.
Mijn laatste poging tot uitleggen:
Ik heb 2 controllers:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class PageBackendController extends Controller
{
public function editAction($id)
{
// ... heel veel form maken en form afhandeling
if ($form->isValid()) {
// ... gegevens opslaan in db
$this->forward('PageBackend:success', array('page' => $page->getName());
}
}
public function successAction($page)
{
// ...
return $this->render(...);
}
}
?>
class PageBackendController extends Controller
{
public function editAction($id)
{
// ... heel veel form maken en form afhandeling
if ($form->isValid()) {
// ... gegevens opslaan in db
$this->forward('PageBackend:success', array('page' => $page->getName());
}
}
public function successAction($page)
{
// ...
return $this->render(...);
}
}
?>
Als ik nu het formulier invul en op submit klik wordt de edit action aangeroepen, die slaat de gegevens op en het tonen van de success message laat hij over aan de success action.
Intern wordt nu de success controller aangeroepen met de parameters, de forward functie zou er zo uitzien:
Code (php)
Het is dus eigenlijk gewoon een method call in PHP, alleen wordt er een andere controller aangeroepen en wordt er op de plaats van de 3 stippen een nieuw Request object aangemaakt.
By the way 1) Waarom forward je naar een functie in dezelfde class, ipv gewoon $this->successAction() te doen?
By the way 2) Ik gebruik PHP 5.4.9 en merk dat het niet meer uitmaak hoe ik een class-/functienaam aanroep.
$boe = new Boe(); $boe->doeIets(); levert hetzelfde resultaat op als $boe = new bOe(); $boe->DOEietS();
Dat was vroeger toch niet zo?
Code (php)
Terwijl anders() niet eens static is!
// E: Of nee ik zit niet met hetzelfde probleem, maar het is wel een probleem xD
Gewijzigd op 04/01/2013 00:25:42 door - Raoul -
Quote:
1) Waarom forward je naar een functie in dezelfde class, ipv gewoon $this->successAction() te doen?
Omdat de success action recht heeft op een eigen request. Dat is in dit geval natuurlijk zinloos, maar ik kan nu even op geen beter voorbeeld komen.
Quote:
Dat was vroeger toch niet zo?
Getest met PHP5.2.7 en dan werkt het ook, maar het lijkt erop alsof het een configuratie optie is (denk ik). Ik raad het in elk geval niet aan te doen.
"...maar ik kan nu even op geen beter voorbeeld komen."
Lekker is dat :)
"Getest met PHP5.2.7 en dan werkt het ook, maar het lijkt erop alsof het een configuratie optie is (denk ik). Ik raad het in elk geval niet aan te doen."
Hmmm, ik ben er ook geen voorstander van eerlijk gezegd, maar ik weet ook niet of (en zo ja hoe) ik dit gedrag kan uitzetten. Ik vind het maar raar. Kan me niet herinneren dat ik het eerder gezien heb... maar als het bij jou ook gebeurt?? Vreemd...
Gewijzigd op 04/01/2013 00:29:54 door - Raoul -
Maar dan ben ik ook wel benieuwd waarom?
Waarom zou je een method, die in dezelfde class staat, laten aanroepen door een andere class? Wat ook nog eens vertragend werkt? Ik zie het nut er op dit moment (nog) niet van in, maar jij blijkbaar wel... dus vertel...
Gewijzigd op 04/01/2013 00:34:31 door Ozzie PHP
Dat heb je goed. Als je bezig bent met OO moet je alles vanuit een logisch oogpunt zien, $this->successAction() callen kan wel. Maar als je met requests werkt is het altijd logischer om een aparte request aan te maken en die te forwarden, want je laad als het ware een andere pagina in, en een andere pagina inladen, is dan ook weer een nieuwe request.
Maar leg me aub dan eens uit wat jij verstaat onder een request? Wat is volgens jou een request?
Ozzie PHP op 04/01/2013 00:39:26:
Maar leg me aub dan eens uit wat jij verstaat onder een request? Wat is volgens jou een request?
Een request? Dat is een pagina die je inlaad. Of een poging doen tot het inladen van een pagina.