Request-Verarbeitung

1. Einleitung

Die Verarbeitung einer Benutzer-Anfrage ist zentraler Bestandteil einer Web-Applikation. Die in diesem Bereich anfallenden Aufgaben sind:

  • Entgegennahme der Anfrage: Dies findet idealerweise über einen zentralen Einstiegspunkt statt um zentrale Aufgaben wie Konfiguration, Filterung und Logging einfach abbilden zu können (DRY- und Bootstrapping-Prinzip).
  • Prüfung und Verarbeitung der Benutzer-Eingaben: In diesem Schritt werden die Inhalte beispielsweise zum Schutz gegen XSS oder SQL-Injection gefiltert.
  • Initialisierung der Anwendung: Die Nutzer-Eingaben werden nun - insbesondere bei dynamischen Anwendungen - zur Initialisierung der Anwendung genutzt um beispielsweise zu definieren, welche Seite angezeigt werden soll.
  • Generierung der Ausgabe: Der Kern der Anwendung führt nun die notwendige Logik aus und kümmert sich um die Generierung der notwendigen Ausgaben. Dies umfasst in der Regel das anzugeigende HTML oft aber auch andere dynamische Teile (Bilder, CSS, Java Script, AJAX-Antworten).
  • Rückgabe der Antwort: Im Anschluss an die Ausführung der Anwendung wird die generierte Antwort an den Besucher ausgeliefert. In diesem Schritt finden oft zusätzliche Schritte wie die Filterung und/oder Aufbereitung der Ausgabe statt.

Das APF unterstützt Sie in allen genannten Bereichen mit erprobten Lösungen, die auf anerkannten Software-Design-Pattern basieren.

Für die Entgegennahme der Anfrage lässt sich das Bootstrapping-Konzept in Verbindung mit dem Front-Controller nutzen. Letzterer kümmert sich um den kompletten Lifecycle der Verarbeitung einer Benutzer-Anfrage und bietet viele Möglichkeiten eigene Funktionalitäten einzuhängen.

Die Prüfung und Verarbeitung von Benutzer-Eingaben kann sehr einfach mit Hilfe von Filtern erledigt werden. Neben den vom APF mitgelieferten Implementierungen, die bereits einen Großteil der üblichen Anwendungsfälle abdecken können diese sehr einfach erweitert oder ersetzt werden um die Anforderungen Ihrer Anwendung anzudecken.

Für die Initialisierung der Anwendung steht das Konzept der Front-Controller-Actions zur Verfügung. Die nach dem gleichnamigen Software-Entwurfsmuster benannten Komponenten lassen sich beispielsweise dazu einsetzen, innerhalb der HMVC-Anwendung gemeinsam genutzte Informationen in einem Model zu sammeln. Details lassen sich im Kapitel Front-Controller nachlesen.

Zur Generierung der Ausgabe steht ein umfassendes Set an Hilfsmittel zur Verfügung. Hierzu zählt in erster Linie der Page-Controller, der basierend auf dem HMVC-Pattern, die Implementierung von generischen und wiederverwendbaren Modulen unterstützt. Nutzen Sie die Übersicht auf der Seite Komponenten-Dokumentation für Details zu weiteren Tools. Für die Rückgabe der Antwort lassen sich ebenfalls Filter nutzen.

2. Grundlagen

Die Verarbeitung des HTTP-Requests und natürlich die Beantwortung durch einen HTTP-Response wird durch den Front-Controller gesteuert. Dabei greifen sowohl der Front-Controller und dort registrierte Actions als auch die verwendeten Input- und Output-Filter auf die im APF vorhandene Abstraktion von Request und Response zurück.

Die Abstraktion der von PHP gelieferten Mechanismen und Inhalte bietet mehrere Vorteile:

  • Statt der Nutzung von globalen Arrays (z.B. $_REQUEST) und native Funktionen lässt sich eine wohldefinierte, objektorientierte API nutzen.
  • Oft benötigte Funktionalitäten (z.B. Auslesen von Parametern inkl. Rückgriff-Wert) sind bereits vorhanden.
  • Vorhandene Stolpersteine im Umgang mit den von PHP gelieferten Mechnismen und Funktionen werden für Sie aus dem Weg geräumt und durch eine klar strukturierte API nicht mehr zum Problem.

Die Abstraktion von Request und Response im APF besteht aus mehreren Teilen: der gleichnamigen Interface-Definition, den Implementierungen RequestImpl und ResponseImpl und dem Mixin (Trait) GetRequestResponse.

Um die Implementierung von Request und Response auszutauschen, fügen Sie bitte folgendes zu Ihrer Bootstrap-Datei nach dem Inkludieren der APF/core/bootstrap.php hinzu:
PHP-Code
Frontcontroller::$requestImplClass = 'VENDOR\request\CustomRequestImpl'; Frontcontroller::$responseImplClass = 'VENDOR\request\CustomResponseImpl';
Die Methoden GetRequestResponse::getRequest() und GetRequestResponse::getResponse() liefern dann jeweils die von Ihnen definierte Implementierung statt RequestImpl und ResponseImpl zurück.

Die folgenden Kapitel beschreiben die Anwendung der Request und Response Abstraktion innerhalb Ihrer Applikation.

3. Der Request

Das Interface Request beschreibt die Struktur einer HTTP-Anfrage an eine APF-basierte Applikation. Es beinhaltet Konstanten für oft verwendete Definitionen sowie Methoden zur Abfrage und Manipulation von Inhalten. Der folgende Code-Block zeigt die Definition des Interface (gekürzt):

PHP-Code
namespace APF\core\http; interface Request { const METHOD_GET = 'GET'; const METHOD_POST = 'POST'; ... const DEFAULT_PROTOCOL_IDENTIFIER = 'http'; const SECURE_PROTOCOL_IDENTIFIER = 'https'; ... public function getParameter($name, $default = null); public function getGetParameter($name, $default = null); public function getPostParameter($name, $default = null); public function getParameters(); public function getGetParameters(); public function getPostParameters(); public function setParameter($name, $value); public function setGetParameter($name, $value); public function setPostParameter($name, $value); ... public function getRequestUri(); public function getHost(); public function getPath(); public function getHeaders(); public function isSecure(); public function getUrl($absolute = false); public function getReferrerUrl($absolute = false); public function getCookies(); public function getCookie($name); ... }

Die Implementierung des Interfaces - die Klasse RequestImpl - besitzt darüber hinaus noch eine Reihe von Convenience Methoden zur Vereinfachung der Implementierung. Details hierzu erfahren Sie in den nächsten Kapiteln.

3.1. Beziehen des Request

Die Instanz des Requests ist innerhalb der Anwendung eindeutig. Aus diesem Grund wird diese über die Singleton-Implementierung bezogen. Details hierzu finden Sie unter Erzeugung von Objekten.

In allen Klassen, die von

  • APF\core\pagecontroller\Document,
  • APF\core\pagecontroller\BaseDocumentController,
  • APF\core\frontcontroller\AbstractFrontcontrollerAction oder
  • APF\tools\form\validator\AbstractFormValidator

ableiten steht die statische Methode getRequest() zur Verfügung. In allen anderen Klassen lässt sich das Trait APF\core\http\mixins\GetRequestResponse nutzen um die Funktionalität zur Verfügung zu stellen.

Möchten Sie die Instanz der aktuellen Anfrage beziehen, so lässt sich folgender Code nutzen:

PHP-Code
$request = $this->getRequest();

Die Variable $request beinhaltet nun eine Instanz der Klasse RequestImpl.

Möchten Sie die Instanz ausserhalb einer Klasse beziehen, so können Sie den nachfolgend abgedruckten Code nutzen:

PHP-Code
$request = Singleton::getInstance(RequestImpl::class);

3.2. Abfragen von Parametern

Zur Abfrage von Parametern bietet die Klasse RequestImpl verschiedene Möglichkeiten. Möchten Sie einen Parameter unabhängig von der Art der Anfrage (z.B. GET bzw. POST) abfragen, so bietet sich die Nutzung der Funktion getParameter() an:

PHP-Code
$foo = $request->getParameter('foo');

Die Methode getParameter() unterstützt zudem die Übergabe eines Standard- bzw. Rückgriffwertes sollte der Parameter in der akuellen Anfrage nicht enthalten sein:

PHP-Code
$foo = $request->getParameter('foo', 'bar');

Möchten Sie den Wert eines Parameters nur dann erhalten, wenn eine entsprechende Aufruf-Methode gewählt wurde (z.B. POST), so können Sie dazu die Methode getPostParameter() nutzen:

PHP-Code
$foo = $request->getPostParameter('foo');

Die Variable $foo wird nur dann einen Wert ungleich null enthalten, wenn der Parameter foo in einer POST-Anfrage enthalten ist. Ebenso verhält es sich mit der Methode getGetParameter() bei einer GET-Anfrage.

Möchten Sie einen Parameter nur im Fall eines PUT-Requests auswerten lässt sich auch ohne Convenience-Methode folgender Code anwenden:

PHP-Code
$foo = $request->isPut() ? $request->getParameter('foo') : null;

Zur Anfrage aller Parameter der aktuellen Anfrage lassen sich die Funktionen getParameters() bzw. getPostParameters() und getGetParameters() einsetzen. Sie liefern ein assoziatives Array mit den Namen der Parameter und deren Werte zurück.

Beabsichtigen Sie, alle GET-Parameter auszulesen, können Sie folgenden Code-Block nutzen:

PHP-Code
$params = $request->getGetParameters();

Möchten Sie prüfen, ob die Parameter in der aktuellen Anfrage mitgesendet wurde, genügt folgende Prüfung:

PHP-Code
if($request->hasParameter('foo')) { ... }

Auch hier stehen Ihnen die Methoden hasGetParameter() und hasPostParameter() zur Prüfung von Parametern in einer GET- bzw. POST-Anfrage zur Verfügung.

Sowohl getGetParameter() als auch getPostParameter() unterstützen die Übergabe von Standard- bzw. Rückgriffwerten.

3.3. Manipulation des Requests

Möchten Sie Details Ihrer Anwendung nach aussen verstecken, bietet sich die Implementierung von geeigneten Input- und Output-Filtern an. Mit deren Hilfe lassen sich interne Information in eine externe Repräsentation umwandeln und bei Entgegennahme einer solchen Anfrage daraus der interne Zustand wiederherstellen.

Zur Manipulation des Requests bringen das gleichnamige Interface und die dazugehörige Implementierung RequestImpl geeignete Methoden mit.

Soll innerhalb eines Filters bei jedem Request ein definierter Parameter gesetzt werden - beispielsweise die aktuelle Anfrage-Zeit -, so lässt sich das mit Hilfe des folgenden Code-Blocks erledigen:

PHP-Code
$request = $this->getRequest(); $request->setParameter('request-time', time());

Dabei lässt sich der Parameter mit Hilfe der Methode getParameter() wieder abrufen. Möchten Sie analog zu der in Kapitel 3.2 beschrieben Vorgehensweise Parameter für konkrete Anfrage-Methoden definieren, so lässt sich dies mit Hilfe der Funktionen setGetParameter() und setPostParameter() erledigen.

Das Löschen von Parametern kann entweder für konkrete Parameter oder für die komplette Anfrage erfolgen. Auch hier ist eine Löschung an Hand der Anfrage-Methode möglich. Die folgende Code-Box zeigt das Löschen eines konkreten Parameters:

PHP-Code
$request = $this->getRequest(); // Löschen eines einzelnen Request-Parameters $request->deleteParameter('foo'); // Löschen eines GET Request-Parameters (POST Parameter bleibt erhalten) $request->deleteGetParameter('foo'); // Löschen eines POST Request-Parameters (GET Parameter bleibt erhalten) $request->deletePostParameter('foo');

Sollen mehrere, ausgewählte Parameter entfernt werden, so lässt sich folgendes Code-Beispiel nutzen:

PHP-Code
$request = $this->getRequest(); // Löschen mehrerer Request-Parameter $request->deleteParameters(['foo', 'bar', 'baz']); // Löschen mehrerer GET Request-Parameter (POST Parameter bleiben erhalten) $request->deleteGetParameter(['foo', 'bar', 'baz']); // Löschen mehrerer POST Request-Parameter (GET Parameter bleiben erhalten) $request->deletePostParameter(['foo', 'bar', 'baz']);

Zum Löschen aller Parameter stehen folgende Funktionen zur Verfügung:

PHP-Code
$request = $this->getRequest(); // Löschen aller Request-Parameter $request->resetParameters(); // Löschen aller GET Request-Parameter (POST Parameter bleiben erhalten) $request->resetGetParameters(); // Löschen aller POST Request-Parameter (GET Parameter bleiben erhalten) $request->resetPostParameters();

3.4. Auslesen von Cookies

Eine Anfrage kann eine beliebige Anzahl von Cookies beinhalten. Zum Auslesen stehen Ihnen die Methode getCookies() und getCookie() zur Verfügung. Erstere liefert alle mit der Anfrage mitgesendeten HTTP-Cookies zurück, zweitere ein Konkretes.

Der folgende Code-Block zeigt Ihnen, wie sie den Wert eines Cookies auslesen können:

PHP-Code
$request = $this->getRequest(); $cookie = $request->getCookie('name_des_cookies'); $value = null; if($cookie !== null){ $value = $cookie->getValue(); }

Ist das Cookie nicht vorhanden, gibt die Methode getCookie() den Wert null zurück. Möchten Sie zur Vereinfachung der Implementierung den Standard-Wert verändern, nutzen Sie bitte das optionale Argument der Methode getValue().

Die Liste aller gesendeten Cookies lässt sich wie folgt ausgeben:

PHP-Code
$request = $this->getRequest(); foreach($request->getCookies() as $cookie) { echo $cookie->getName() . ':' . $cookie->getValue() . PHP_EOL; }

Die mit der Anfrage mitgesendeten Informationen eines Cookies beschränken sich auf den Namen und den Wert. Angaben wie Domain, Lebensdauer und Informationen zur Sicherheit sind nicht enthalten.

Dies bedeutet, dass ein per getCookies() bzw. getCookie() ausgelesenes Cookie nicht direkt im Response zurück gesendet werden kann. Dies würde auf Grund der fehlenden Angaben entweder zu unerwünschtem Verhalten oder zu Fehlern führen.

Bitte beachten Sie hierzu ebenso die Hinweise in Kapitel 4.5.

3.5. Auslesen von URL und Headern

Über die aktuelle Anfrage lassen sich neben den in den vorangegangenen Kapiteln beschriebenen Inhalte auch die aktuelle und die verweisende URL sowie die HTTP-Header der Anfrage auslesen.

Die aktuelle URL erhalten Sie mit Hilfe der Methoden getUrl() bzw. getRequestUri(), wobei getUrl() eine Instanz der Klasse Url liefert und getRequestUri() lediglich eine Zeichenkette. Das folgende Code-Beispiel zeigt die Nutzung der beiden Methoden:

PHP-Code
$request = $this->getRequest(); // Generieren einer Ziel-URL über die Url-Abstraktion $url = $request->getUrl(); $successPageUrl = LinkGenerator::generateUrl($url->setQueryParameter('view', 'success')); // Generieren einer Ziel-URL über die Zeichenkette $url = Url::fromString($request->getRequestUri()); $successPageUrl = LinkGenerator::generateUrl($url->setQueryParameter('view', 'success'));

Details zur Generierung von Links erhalten Sie im Kapitel Links.

Mit Hilfe der Funktionen getReferrerUrl() bzw. getReferrer() lassen sich die verweisenden Seiten auslesen. Dabei gibt getReferrerUrl() analog zu getUrl() eine Instanz der Klasse Url zurück, die sich direkt weiter verarbeiten lässt und getReferrer() lediglich eine Zeichenkette.

Die Header der aktuellen Anfrage lassen sich via getHeaders() bzw. getHeader() auslesen. Um festzustellen, ob eine Anfrage mit einem bestimmten Zeichensatz beantwortet werden soll, kann folgender Code genutzt werden:

PHP-Code
$request = $this->getRequest(); $requestedCharset = 'utf-8'; $header = $request->getHeader('Accept-Charset'); if($header !== null) { $requestedCharset = $header->getValue(); }

Die Liste aller Header kann mit folgendem Code-Schnipsel ausgegeben werden:

PHP-Code
$request = $this->getRequest(); foreach($request->getHeaders() as $header) { echo $header->getName() . ':' . $header->getValue() . PHP_EOL; }

3.6. Weitere Methoden

Neben den bisher genannten Methoden stellt die Request-Implementierung RequestImpl noch weitere Methoden zur einfachen Entwicklung von Web-Applikationen zur Verfügung. Die folgende Liste zeigt diese zusammen mit einer Beschreibung auf.

  • getSessionId(): Gibt die aktuelle Session-ID zurück.
  • isSecure(): Liefert true, sofern die Anfrage über eine sichere Verbindung (SSL, TLS) erfolgt ist.
  • getMethod(): Mit Hilfe dieser Methode können Sie die Anfrage-Methode auslesen. Die Werte sind durch die Konstanten Request::METHOD_* repräsentiert.
  • isGet(): Gibt true zurück, wenn es sich um eine GET-Anfrage handelt.
  • isPost(): Gibt true zurück, wenn es sich um eine POST-Anfrage handelt.
  • isPut(): Gibt true zurück, wenn es sich um eine PUT-Anfrage handelt.
  • isDelete(): Gibt true zurück, wenn es sich um eine DELETE-Anfrage handelt.
  • isAjax(): Gibt true zurück, wenn es sich um eine Ajax-Anfrage (z.B. von einer Java-Script-Bibliothek) handelt.
  • isImage(): Gibt true zurück, wenn es sich um eine Bild-Anfrage handelt.
  • isHtml(): Gibt true zurück, wenn es sich um eine einfache Anfrage handelt.
  • isGzipSupported(): Diese Methode kann benutzt werden um abzufragen ob der Client gzip-Kompression unterstützt.
  • isDeflateSupported(): Diese Methode kann benutzt werden um abzufragen ob der Client deflate-Kompression unterstützt.

Details entnehmen Sie bitte der API-Dokumentation.

4. Der Response

Analog zur Definition des Request beschreibt das Interface Response die Struktur der HTTP-Antwort einer APF-basierten Applikation. Es beinhaltet Konstanten für oft verwendete Definitionen sowie Methoden zur Abfrage und Manipulation von Inhalten. Der folgende Code-Block zeigt die Definition des Interface (gekürzt):

PHP-Code
interface Response { const VERSION_1_0 = '1.0'; const VERSION_1_1 = '1.1'; ... const CODE_OK = 200; ... const CODE_MOVED_PERMANENTLY = 301; const CODE_FOUND = 302; const CODE_SEE_OTHER = 303; const CODE_NOT_MODIFIED = 304; const CODE_USE_PROXY = 305; const CODE_TEMPORARY_REDIRECT = 307; ... const CODE_UNAUTHORIZED = 401; ... public function getVersion(); public function setVersion($version); public function getStatusCode(); public function setStatusCode($code); public function getReasonPhrase(); public function setReasonPhrase($phrase); public function getBody(); public function setBody($body, $append = false); public function send($exit = true); public function forward($url, $exitAfterForward = true); public function redirect($url, $permanent = false, $exitAfterForward = true); public function sendNotFound($exitAfterForward = true); public function sendServerError($exitAfterForward = true); public function isSent(); ... public function getHeaders(); public function setHeader(Header $header); public function deleteHeader(Header $header); public function getCookies(); public function setCookie(Cookie $cookie); public function deleteCookie(Cookie $cookie);

Die Implementierung des Interfaces - die Klasse ResponseImpl - besitzt darüber hinaus noch eine Reihe von Convenience Methoden zur Vereinfachung der Implementierung. Details hierzu erfahren Sie in den nächsten Kapiteln.

4.1. Beziehen des Response

Die Instanz des Responses ist innerhalb der Anwendung eindeutig. Aus diesem Grund wird diese über die Singleton-Implementierung bezogen. Details hierzu finden Sie unter Erzeugung von Objekten.

In allen Klassen, die von

  • APF\core\pagecontroller\Document,
  • APF\core\pagecontroller\BaseDocumentController,
  • APF\core\frontcontroller\AbstractFrontcontrollerAction oder
  • APF\tools\form\validator\AbstractFormValidator

ableiten steht die statische Methode getResponse() zur Verfügung. In allen anderen Klassen lässt sich das Trait APF\core\http\mixins\GetRequestResponse nutzen um die Funktionalität zur Verfügung zu stellen.

Möchten Sie die Instanz der aktuellen Anfrage beziehen, so lässt sich folgender Code nutzen:

PHP-Code
$response = $this->getResponse();

Die Variable $response beinhaltet nun eine Instanz der Klasse ResponseImpl.

Möchten Sie die Instanz ausserhalb einer Klasse beziehen, so können Sie den nachfolgend abgedruckten Code nutzen:

PHP-Code
$response = Singleton::getInstance(ResponseImpl::class);

4.2. Definition der Standard-Eigenschaften

Jede Antwort einer HTTP-Kommunikation enthält definierte Bestandteile wie die Version des Protokolls, dem Antwort-Status und einer Beschreibung des Status. Daneben gibt es weitere Meta-Informationen, die als Header verpackt sind. Details zu Headern finden Sie in Kapitel 4.3.

Die Version Ihrer Antwort lässt sich mit Hilfe der Methode setVersion() definieren. Ohne Änderung wird die Antwort immer als Version HTTP/1.1 gesendet. Möchten Sie eine andere Version definieren, lässt sich dies wie folgt erledigen:

PHP-Code
$response = $this->getResponse(); $response->setVersion('1.0');

Für Ihre Applikation interessanter ist die Definition des Status-Codes und der zugehörigen Beschreibung. Nehmen Sie keine Änderung vor, wird Ihre Antwort beim Aufrufer als HTTP/1.1 200 OK ankommen. Möchten Sie durch einen anderen Status Code einen besonderen Umstand (z.B. Seite nicht gefunden) ausdrücken, können Sie den Status wie folgt ändern:

PHP-Code
$response = $this->getResponse(); $response->setStatusCode(Response::CODE_NOT_FOUND);

Alle Standard-Codes werden automatisch in die zugehörige Beschreibung übersetzt. Bei einer 404-Antwort lautet diese Not Found. Möchten Sie diese ändern um weitere Informationen an den Aufrufer zu senden, so nutzen Sie dazu bitte die setReasonPhrase():

PHP-Code
$response = $this->getResponse(); $response->setStatusCode(Response::CODE_NOT_FOUND); $response->setReasonPhrase('Page ' . $_SERVER['REQUEST_URI'] . ' not found!);

Die zum Aufrufer gesendete Antwort lautet in diesem Fall:

Code
HTTP/1.1 404 Page /foo not found!

4.3. Definition von Headern

Neben den Standard-Eigenschaften lässt sich eine HTTP-Antwort mit weiteren Meta-Eigenschaften in Form von HTTP-Headern ausstatten. Für die Implementierung einer Web-Applikation sind hier besonders der in der Antwort zurückgelieferte Datentyp (z.B. HTML, CSS, Bild), die Informationen zur Gültigkeit und Weiterleitungen interessant. Für die Umsetzung von Weiterleitungen stehen die in Kapitel 4.6 beschriebenen, spezielle Methoden zur Verfügung.

Der Datentyp der zurückgelieferten Antwort lässt sich mit entweder mit Hilfe der Convenience-Methode setContentType() oder per setHeader() definieren:

PHP-Code
$response = $this->getResponse(); // Benutzung der Convenience-Methode $response->setContentType('image/png'); // Native Definition eines Headers $response->setHeader(new HeaderImpl(HeaderImpl::CONTENT_TYPE, 'image/png'));

Mit Hilfe der nativen Definition von Headern lassen sich beliebige Meta-Daten in der HTTP-Antwort definieren. Die folgende Code-Box zeigt einige gängige Beispiele:

PHP-Code
$response = $this->getResponse(); // Definiert das Datum der Anfrage $response->setHeader(new HeaderImpl('Date', date('%Y-%m-%d %H:%i:%s'))); // Erlaubt das Zwischenspeichern der Antwort in Caches und Proxies $response->setHeader(new HeaderImpl('Cache-Control ', 'public')); // Definiert den Zeitpunkt der letzten Änderung $response->setHeader(new HeaderImpl('Last-Modified', $lastModificationDate));
Möchten Sie einen bereits gesetzten Header überschreiben, so setzen Sie diesen einfach mit der Methode setHeader(). Die neue Definition überschreibt dabei die alte.

Um einen bereits gesetzten Header zu entfernen nutzen Sie bitte die Methode deleteHeader():

PHP-Code
$response = $this->getResponse(); $response->deleteHeader(new HeaderImpl('Date', null));

Um alle bereits gesetzten Header zu entfernen, nutzen Sie bitte die Methode resetHeaders():

PHP-Code
$response = $this->getResponse(); $response->resetHeaders();

4.4. Füllen des Bodies

In der Regel beinhaltet die Antwort einer Anfrage einen Inhalt (z.B. HTML-Code). Um den Response mit Inhalt zu füllen können Sie die Methode setBody() nutzen. Diese unterstützt sowohl das Setzen des Inhalts als auch das Anhängen von weiteren Inhalten:

PHP-Code
$response = $this->getResponse(); // Definieren des Inhaltes (überschreibt den bisherigen Inhalt) $response->setBody('...'); // Hinzufügen eines Inhaltes $response->setBody('...', true);

Um den bis zu einem definierten Zeitpunkt im Ablauf der Applikation generierten Inhalt abzufragen, nutzen Sie bitte die Funktion getBody().

Die Definition des Inhalts wird bei der Ausführung des Front-Controller bereits für Sie übernommen. Das explizite Setzen des Inhalts ist in der Regel nur in Front-Controller-Actions notwendig. Details hierzu entnehmen Sie bitte Kapitel 4.7.

4.5. Setzen und Löschen von Cookies

Beabsichtigen Sie in Ihrer Applikation Inhalte in einem Cookie speichern, so lässt sich dazu die Methode setCookie() nutzen. Hierzu konstruieren Sie zunächst das gewünschte Cookie und geben es der Response-Instanz mit:

PHP-Code
$cookie = new Cookie('name_des_cookies', Cookie::DEFAULT_EXPIRATION_TIME, 'www.example.com'); $cookie->setValue('Gewuenschter Wert'); $response = $this->getResponse(); $response->setCookie($cookie);
Bitte beachten Sie, dass der Wert eines Cookies vom Typ string ist. Beabsichtigen Sie komplexere Strukturen zu speichern, müssen Sie selbst für die De- und Encodierung sorgen. Hierzu können beispielsweise die Funktionen serialize() und unserialize() genutzt werden.
Bitte beachten Sie weiterhin, dass die Größe von Cookies direkten Einfluss auf die Anfrage-Performance hat, da Cookies im HTTP-Anfragen mitgeliefert werden. Achten Sie daher immer auf eine möglichst kleine Datenmenge. Die Datenmenge kann beispielsweise durch ein eigenes, komprimiertes Datenformat oder durch Nutzung von Komprimierungsfunktionen erreicht werden.

Möchten Sie ein bereits gesetztes Cookie verändern, so lässt sich dies mit Hilfe des folgenden Codes erledigen:

PHP-Code
$request = $this->getRequest(); $cookie = $request->getCookie('name_des_cookies'); $cookie ->setExpireTime(86400 * 2) ->setDomain('other.example.com') ->setPath('/foo/bar') ->setHttpOnly(true) ->setSecure(false); $response = $this->getResponse(); $response->setCookie($cookie);

Bitte beachten Sie, dass für ein bereits gesetztes Cookies nicht alle Informationen im Request mitgeliefert werden. Aus diesem Grund sollten Sie - sofern gewünscht und relevant - bei der Wiederverwendung eines ausgelesenen Cookies die Parameter

  • Cookie::expireTime
  • Cookie::domain
  • Cookie::path
  • Cookie::secure
  • Cookie::httpOnly

auf die gewünschten Werte setzen. Bitte nutzen Sie bei einem Update die selben Werte wie beim ersten Setzen.

Details hierzu entnehmen Sie bitte Kapitel 3.4.

Zum Löschen eines Cookies können Sie die Methode Response::deleteCookie() einsetzen. Dieses markiert das übergebene Cookie für den Client als verfallen und zu löschen:

PHP-Code
$response = $this->getResponse(); $response->deleteCookie(new Cookie('name_des_cookies'));
Bitte beachten Sie, dass die Werte des zu löschenden Cookies identisch mit den Werten zur Erstellungszeit sein müssen. Dies bedeutet, dass beispielsweise Domain und Pfad vor dem Aufruf von deleteCookie() auf die entsprechenden Werte gesetzt werden müssen.

4.6. Weiterleitungen

Ein typischer Anwendungsfall einer Web-Applikation ist das Weiterleiten auf diverse Ziel-Seiten - etwa einer Login-Seite - und das Senden von HTTP-Status-Informationen.

Zur Weiterleitung einer Anfrage auf einer andere Ziel-Seite stehen Ihnen die Methoden forward() und redirect() zur Verfügung. Mit Hilfe von forward() lassen sich Weiterleitungen mit einem Status-Code 303 (see other) realisieren, wohingegen redirect() den Status-Code 301 bzw. 302 zurück liefert.

Der folgende Code-Block zeigt typische Anwendungsfälle der beiden Methoden:

PHP-Code
$request = $this->getRequest(); $response = $this->getResponse(); $link = LinkGenerator::generateUrl( $request->getUrl()->mergeQuery(array('param1' => '','param2' => 'new_value')) ); // Verweis auf eine andere Seite $response->forward($link); // Temporäre Weiterleitung $response->redirect($link); // Permanente Weiterleitung $response->redirect($link, true);

Die beiden Methoden forward() und redirect() brechen die weitere Code-Abarbeitung mit einem exit() ab um Code-Injection zu verhindern (siehe Overview of Execution After Redirect Web Application Vulnerabilities).

Um dieses Verhalten in Unit-Tests abschalten zu können, bietet die Klasse ResponseImpl die Methoden deactivateExitAfterForward() und activateExitAfterForward() um das Verhalten global aus, bzw. einzuschalten:

PHP-Code
$response = $this->getResponse(); // Verarbeitung nach Weiterleitung abbrechen $response->activateExitAfterForward(); // Verarbeitung nach Weiterleitung weiter führen (z.B. für Unit-Tests) $response->deactivateExitAfterForward();

Um innerhalb eines konkreten Aufrufs von forward() oder redirect() einen Abbruch zu erreichen, lassen sich die optionalen Parameter $exitAfterForward auf false setzen.

Mit Hilfe der Methoden sendNotFound() und sendServerError() lässt sich der Client über einen Fehler in der Applikation informieren. sendNotFound() sendet Status-Code 404 um anzuzeigen, dass die gewünschte Seite nicht gefunden wurde und sendServerError() sendet Status-Code 500 (Server-Fehler).

4.7. Senden der Antwort

Möchten Sie die Antwort einer Anfrage an den Client senden, lässt sich das auf zwei Arten erledigen: direkte Ausgabe des Response per echo oder mit Hilfe der Methode send().

Nutzen Sie die Funktion echo, so lässt sich der Text Hallo Welt! wie folgt an den Client senden:

PHP-Code
$response = $this->getResponse(); $response->setBody('Hallo Welt!'); echo $response;

Sofern Sie Kontrolle über die Request-Verarbeitung benötigen - beispielsweise um diese in einer Front-Controller-Action zu beenden - bietet sich die Nutzung der Methode send() an:

PHP-Code
$response = $this->getResponse(); $response->setBody('Hallo Welt!'); $response->send();

Möchten Sie den Response vor dem Senden an den Client in der Bootstrap-Datei manipulieren, so lässt sich das wie folgt erreichen:

PHP-Code
$fC = Singleton::getInstance(Frontcontroller::class); $response = $fC->start('...', '...'); $version = '3.0'; $response->setBody('<!-- Software-Version: ' . $version . ' -->', true); $response->setHeader(new HeaderImpl('X-Software-Version', $version)); echo $response;

4.8. Debugging

Um den vollständigen Inhalt einer Antwort zu Debugging-Zwecken auszugeben lässt sich die Methode dump() einsetzen. Diese lässt sich beispielsweise in der Bootstrap-Datei nutzen um alle gesendeten Header und den Inhalt der Anfrage anzuzeigen:

PHP-Code
$fC = Singleton::getInstance(Frontcontroller::class); $response = $fC->start('...', '...'); echo $response->dump();
Bitte beachten Sie, dass die Seite im Browser ggf. nicht wie erwartet angezeigt wird, da zur Darstellung notwendige HTTP-Header nicht gesendet werden. Benutzen Sie die Methode dump() daher nur zu Debugging-Zwecken.

Kommentare

Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
Für diesen Artikel liegen aktuell keine Kommentare vor.