Heim > Backend-Entwicklung > PHP-Tutorial > Eine Einführung in das Front -Controller -Muster, Teil 2

Eine Einführung in das Front -Controller -Muster, Teil 2

Lisa Kudrow
Freigeben: 2025-02-26 09:55:45
Original
815 Leute haben es durchsucht

An Introduction to the Front Controller Pattern, Part 2

Kernpunkte

  • Der Front-End-Controller fungiert als zentraler Proxy für die Anwendung und weist vordefinierte Handler wie Seitencontroller oder REST-Ressourcen Befehle zu.
  • Der Front-End-Controller kann eine kompakte Struktur, einen Routen- und Versandanforderungen beibehalten und auch auf einen voll funktionsfähigen Rastful-Controller erweitert werden, HTTP-Verben analysieren, sich an Pre/Post-Versandhaken usw. anpassen.
  • Dieser Artikel zeigt, wie ein kleines, aber skalierbares HTTP-Framework bereitgestellt wird, das mit Front-End-Controllern, eigenständigen Routern und Schedulern funktioniert, während die Anfrage-/Antwortzyklen unabhängig voneinander bearbeitet werden.
  • Der Autor führte auch den Prozess des Erstellens eines Front-End-Controllers von Grund auf neu ein, einschließlich des Definierens von Klassen zum Simulieren von Daten und Verhaltensweisen typischer HTTP-Anforderungs-/Antwortzyklen, dem Erstellen von Routing-Modulen und der Einrichtung von Schedulern.
  • Der
  • -Modus für den Front-End-Controller hat die Vorteile einer zentralisierten Steuerung, der Verringerung der Code-Duplikation und der Verbesserung der Modularität und der Trennung von Bedenken, ist jedoch möglicherweise nicht für alle Webanwendungen geeignet und kann zu einem einzigen Fehlerpunkt führen, wenn sie unsachgemäß implementiert.

Der Front-End-Controller ist wie ein zentraler Proxy in einer Anwendung, und sein Hauptfokusbereich besteht darin, vordefinierten Handlern wie Seitencontroller, REST-Ressourcen oder irgendetwas anderes Befehle zuzuweisen, das in den Sinn kommt . Das Aufbau von mindestens einem einfachen Front-End-Controller ist eine sehr nützliche Erfahrung, um ihre Details zu verstehen und diese Idee aus pragmatischer Sicht zu fördern, habe ich in einem einführenden Post die Implementierung eines künstlichen Front-End-Controllers eingeführt, der Routing und Route und wird Alle für das Versand von Anfragen erforderlichen Logik sind innerhalb der Grenzen einer Klasse verpackt. Einer der besten Aspekte von Front-End-Controllern ist, dass Sie sie nur als kompakte Strukturen, Routen- und Versandanträge aufbewahren können oder Ihre Kreativität zeigen und einen voll funktionsfähigen Rastful-Controller implementieren können, der HTTP-Verben analysieren kann, Anpassung vor/Post Entsenden Sie Hooks usw., alles hinter einer einheitlichen API. Obwohl dieser Ansatz attraktiv ist, verstößt er gegen das Prinzip der einzelnen Verantwortung (SRP) und die Art der OOP selbst, die verschiedene Aufgaben proaktiv an mehrere feinkörnige Objekte delegiert. Bedeutet das also, dass ich nur eine andere sündige Seele bin, die es wagt, die SRP -Vorschriften zu brechen? In gewisser Weise ja. Daher möchte ich meine Sünde beseitigen, indem ich Ihnen zeige, wie Sie ein kleines, aber skalierbares HTTP-Framework problemlos bereitstellen können, das mit Front-End-Controllern mit eigenständigen Routern und Schedulern arbeiten kann. Darüber hinaus wird der gesamte Antrags-/Antwortzyklus unabhängig von mehreren wiederverwendbaren Klassen behandelt, die natürlich nach Belieben eingestellt werden können. Angesichts der Tatsache, dass es eine große Anzahl von mit voll befriedigten Komponenten gepackten HTTP-Frameworks gibt, erscheint es lächerlich, einen Front-End-Controller zu implementieren, der Anfragen von Grund auf neu stellt und entsendet, obwohl diese Klassen die Art von SRP behalten. Um zu vermeiden, dass das Rad neu erfunden wird, werden einige Teile meiner benutzerdefinierten Implementierung von der von Lars Strojny geschriebenen Clever EphpMVC -Bibliothek inspiriert.

Analysieren Sie die Anforderung/Routing/Planung/Antwortzyklus

Die Aufgabe, die wir zuerst lösen sollten, besteht darin, mehrere Klassen zu definieren, die für die Simulation von Daten und das Verhalten typischer HTTP -Anforderungs-/Antwortzyklen verantwortlich sind. Dies ist die erste Klasse und die Schnittstelle, die sie implementiert:

<code>class Request {

  public function __construct($uri, $params) { 
    $this->uri = $uri;
    $this->params = $params;
  }

  public function getUri() {
    return $this->uri;
  }

  public function setParam($key, $value) {
    $this->params[$key] = $value;
    return $this;
  }

  public function getParam($key) {
    if (!isset($this->params[$key])) {
      throw new \InvalidArgumentException("The request parameter with key '$key' is invalid."); 
    }
    return $this->params[$key];
  }

  public function getParams() {
    return $this->params;
  }
}</code>
Nach dem Login kopieren
Die

Die Anforderungsklasse verkaps das eingehende URI- und Parameter -Array und simuliert eine extrem einfache HTTP -Anforderung. Für die Kürze wurden zusätzliche Datenelemente wie die mit der entsprechende Anfrage verbundene Methode absichtlich ausgeschlossen. Wenn Sie sie der Klasse hinzufügen möchten, fahren Sie fort. Es ist gut, eine dünne HTTP -Anforderungsverpackung zu haben, die unabhängig existiert, aber es wird nutzlos, ohne sich mit den entsprechenden Teilen der Daten und des Verhaltens zu koppeln, die eine typische HTTP -Antwort simuliert. Lassen Sie uns diese ergänzende Komponente beheben und erstellen:

<code>class Response {
  public function __construct($version) {
    $this->version = $version;
  }

  public function getVersion() {
    return $this->version;
  }

  public function addHeader($header) {
    $this->headers[] = $header;
    return $this;
  }

  public function addHeaders(array $headers) {
    foreach ($headers as $header) {
      $this->addHeader($header);
    }
    return $this;
  }

  public function getHeaders() {
    return $this->headers;
  }

  public function send() {
    if (!headers_sent()) {
      foreach($this->headers as $header) {
        header("$this->version $header", true);
      }
    } 
  }
}</code>
Nach dem Login kopieren

Die Antwortklasse ist zweifellos aktiver als ihre Partneranfrage. Es fungiert als Basisbehälter, mit dem Sie HTTP -Header nach Belieben stapeln können, und kann sie an den Kunden senden. Da diese Klassen ihre Operationen unabhängig ausführen, ist es an der Zeit, den nächsten Teil des Front-End-Controllers aufzubauen. In einer typischen Implementierung wird der Routing-/Versandprozess meist im selben Ansatz eingekapselt, was ehrlich gesagt überhaupt nicht schlecht ist. In diesem Fall ist es jedoch besser, diese Prozesse aufzubrechen und an verschiedene Klassen zu delegieren. Auf diese Weise werden die Dinge in Bezug auf die gleiche Verantwortung ausgeglichener. Hier sind die Stapel von Klassen, die das Routing -Modul ausführen:

<code>class Route {

  public function __construct($path, $controllerClass) {
    $this->path = $path;
    $this->controllerClass = $controllerClass;
  }

  public function match(RequestInterface $request) {
    return $this->path === $request->getUri();
  }

  public function createController() {
   return new $this->controllerClass;
  }
}


class Router {
  public function __construct($routes) {
    $this->addRoutes($routes);
  }

  public function addRoute(RouteInterface $route) {
    $this->routes[] = $route;
    return $this;
  }

  public function addRoutes(array $routes) {
    foreach ($routes as $route) {
      $this->addRoute($route);
    }
    return $this;
  }

  public function getRoutes() {
    return $this->routes;
  }

  public function route(RequestInterface $request, ResponseInterface $response) {
    foreach ($this->routes as $route) {
      if ($route->match($request)) {
        return $route;
      }
    }
    $response->addHeader("404 Page Not Found")->send();
    throw new \OutOfRangeException("No route matched the given URI.");
  }
}</code>
Nach dem Login kopieren

Wie man vielleicht erwartet, gibt es bei der Implementierung funktionaler Routing -Mechanismen viele Optionen. Zumindest meiner Meinung nach ist die obige Methode sowohl praktisch als auch direkt. Es definiert eine separate Routenklasse, die den Pfad an einen bestimmten Betriebscontroller bindet, und einen einfachen Router, dessen Verantwortung darauf beschränkt ist, zu überprüfen, ob die gespeicherte Route mit dem URI übereinstimmt, das einem bestimmten Anforderungsobjekt zugeordnet ist. Um das Problem endlich zu lösen, müssen wir einen schnellen Scheduler einrichten, der neben der vorherigen Klasse nebeneinander verwendet werden kann. So macht die folgende Klasse:

<code>class Dispatcher {

  public function dispatch($route, $request, $response)
    $controller = $route->createController();
    $controller->execute($request, $response);
  }
}</code>
Nach dem Login kopieren

Scannen Sie den Dispatcher und Sie werden zwei Dinge bemerken. Erstens trägt es keinen Zustand. Zweitens wird implizit davon ausgegangen, dass jeder Betriebscontroller unter der Oberfläche der Execute () -Methode ausgeführt wird. Dies kann auf ein etwas flexibleres Muster neu ausgerichtet werden, wenn Sie möchten (das erste, was Ihnen in den Sinn kommt, ist, die Implementierung der Routenklasse zu optimieren), aber der Einfachheit halber werde ich den Scheduler unverändert halten. Bisher fragen Sie sich vielleicht, wie Sie einen Front-End-Controller platzieren können, der alle früheren Klassen miteinander kombinieren kann. Mach dir keine Sorgen, als nächstes ist es!

(aufgrund von Platzbeschränkungen wird der nachfolgende Inhalt abgeschnitten. Bitte geben Sie den Rest des Inhalts an und ich werde den Pseudooriginal weiter vervollständigen.)

Das obige ist der detaillierte Inhalt vonEine Einführung in das Front -Controller -Muster, Teil 2. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage