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();
Het is maar net wat je onder een 'request' verstaat.
Als je een HTTP-request bedoeld (dus aantal bestanden downloaden voor bekijken website): nee.
Als je het als interne PHP-aanroep ziet wel.
"Ozzie, het is niet het includen van een bestand het is het aanroepen van een compleet nieuwe controller..."
Ja, snap ik... maar in jouw voorbeeld heeft dat toch geen toegevoegde waarde (omdat de action in dezelfde class staat)?
Ik bedoel met een request een http-request, ofwel een pagina-aanroep. Jij verstaat onder een request ook een interne (controller/method) aanroep. Daar zit 'm het verschil. Een request zoals ik het bedoel, daarvan kun je er maar een per pagina-aanroep hebben.
Om weer wat dichter bij elkaar te komen: Als jij het idee van een static en singleton class achterwege laat ben ik al tevreden, dan kun je later altijd nog van mening veranderen over wat wel en niet een request is.
Om meteen weer een ander onderwerp erin te gooien: Je moet nooit super globals gebruiken in je klasse. Wat je nu hebt is dus naar mijn mening fout. Gebruik de server array bij het aanmaken van de request klasse, niet in de request klasse.
Om het aanmaken van een request object dan wat te versimpelen zou je een factory kunnen maken, zie bijv. de symfony request klasse en zijn Request::createFromGlobals method.
Wouter, thanks voor je reactie. Waarom zou je een superglobal niet rechtstreeks in je class gebruiken?
Zou het dan bijv. beter zijn als ik in de construct van de request class zou zetten:
$this->server = $_SERVER;
en vervolgens overal die $this->server gebruiken?
Ik wil het allemaal ook niet te moeilijk maken, en vooral zo effectief mogelijk programmeren. Anders ben ik over 2 jaar nog bezig. Het gaat er mij vooral om dat de code logisch in elkaar zit en er geen "gevaar" in de code schuilt waardoor ik gehackt zou kunnen worden. Dat vind ik het meest belangrijk. De code moet voor mij vooral goed zijn, maar hoeft niet per se "mooi" te zijn. Vergelijk het met een auto. Je hebt hele mooie dure auto's die er supergelikt uitzien en waarbij ieder detail op de juiste plek zit. Zo hoeft mijn framework niet te zijn. Ik heb liever een goede middenklasser die me veilig van A naar B brengt. Mja, rare vergelijking, maar ik hoop dat je begrijpt wat ik bedoel.
Ja, alleen gebruik geen anti-patterns dat is het belangrijkste wat ik aan je wil meegeven.
Ozzie, omdat je dan als klasse dingen gaat gebruiken uit de buitenwereld, dat is ten strengste verboden. Iets in de constructor zetten is alsnog de server super global gebruiken. De basis is:
<?php
class
class Request
{
/**
* @var array (of ParameterBag als je dat gebruikt)
*/
private $server;
/**
* @param array $server The server details
*/
public function __construct($server, ...)
{
$this->setServer($server);
}
/**
* @return array // wordt dan ParameterBag als je dat gebruikt
*/
public function getServer()
{
return $this->server;
}
private function setServer(array $server)
{
$this->server = $server; // eventueel een ParameterBag maken
}
}
$request = new Request($_SERVER, ...);
// of, om het makkelijker te maken en niet telkens elke superglobal te moeten inserten
$request = Request::createFromGlobals();
class Request
{
// ...
public static createFromGlobals()
{
return new static($_SERVER);
}
}
?>
Ozzie, als het goed is gebeurd het maar 2 keer ((1) bij de code voor het aanmaken van de request en (2) bij de code voor het aanmaken van een subrequest). En daarom gaf ik ook de 2e optie, daar doe je Request::createFromGlobals en je hebt een nieuwe request.
Ik snap alleen niet wat dit doet:
return new static($_SERVER);
Die createFromGlobals method is een factory method, hij maakt het object aan en geeft hem terug. In dit geval maken we het object aan met de parameter $_SERVER, later krijg je nog meer parameters (alle $_* arrays).
Static verwijst naar de klasse waarin de static method leeft.