Ich denke, man kann mit Sicherheit sagen, dass die meisten Webanwendungen auf dem Anforderungs- / Antwortparadigma basieren. PHP hatte noch nie eine formale Abstraktion dieser Objekte. Eine Gruppe versucht dies zu ändern: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md
In der Frage der Unveränderlichkeit wurden sie jedoch irgendwie von der Seite verfolgt. Einerseits muss das Anforderungs- / Antwortobjekt während seines Lebenszyklus im Allgemeinen nur sehr wenig geändert werden. Andererseits müssen insbesondere für das Antwortobjekt häufig HTTP-Header hinzugefügt werden.
Darüber hinaus hat sich die Unveränderlichkeit im Land der PHP nie wirklich durchgesetzt.
Welche Vorteile sehen Menschen bei der Verwendung unveränderlicher Anforderungs- / Antwortobjekte?
Angenommen, Sie geben ein JSON-Objekt zurück.
$response = new JsonResponse($item);
Schön und einfach. Es stellt sich jedoch heraus, dass es sich bei der Anforderung um eine CORS-Anforderung (Cross-Origin Resource Sharing) handelte. Der Code, der die Antwort generiert, sollte sich nicht darum kümmern, aber irgendwo stromabwärts ist ein Prozess, der die erforderlichen Access-Control-Header hinzufügt. Gibt es einen Vorteil, wenn Sie die ursprüngliche Antwort beibehalten und eine neue mit den zusätzlichen Headern erstellen? Oder ist es nur eine Frage des Programmierstils?
Das Request-Objekt ist etwas interessanter. Es beginnt genauso:
$request = new Request('incoming request information including uri and headers');
Die Anfangsinformationen sollten nicht geändert werden müssen. Wenn die Anforderung weitergeleitet wird, müssen jedoch häufig zusätzliche Verarbeitungsinformationen hinzugefügt werden. Beispielsweise haben Sie möglicherweise einen URL-Matcher, der entscheidet, welche Aktion für eine bestimmte Anforderung ausgeführt werden soll.
$request->setAttribute('action',function() {});
Die eigentliche Ausführung der Aktion liegt in der Verantwortung eines nachgeschalteten Prozesses. Sie könnten eine veränderbare RequestAttributesCollection haben, die die unveränderliche Anfrage umschließt, aber das ist in der Praxis etwas umständlich. Sie könnten auch eine Anfrage haben, die bis auf eine Attributsammlung unveränderlich ist. Ausnahmen sind ebenfalls umständlich. Erfahrungen im Umgang mit solchen Anforderungen?
Antworten:
Ich stimme der Aussage von @ MainMa zu: " Ich bin nicht sicher, ob der geringe Vorteil der Lesbarkeit den möglichen Mangel an Flexibilität kompensiert. " Ich persönlich sehe keine praktischen und nützlichen Aspekte darin,
PHP HTTP Request
temporäre Objekte oderPHP HTTP Response
temporäre Objekte unveränderlich zu machenDas Microsoft-
Windows Presentation Foundation
Framework führt das Konzept der einfrierbaren Objekte ein . Einmal gefroren, werden solche ObjekteObwohl es als GUI-Geschwindigkeitsoptimierung verwendet wird, ist das Konzept selbst auch anderswo anwendbar, einschließlich seiner Vorteile
Nancy
("Leichtes, zeremonielles Framework zum Erstellen von HTTP-basierten Diensten auf .Net und Mono") beschreibt den Vorteil der Unveränderlichkeit in einem der Commit-Kommentare alsIch habe keine andere bemerkenswerte Kommentare über Unveränderlichkeit finden, aber der Nutzen von wieder verwendbaren, zwischenspeicherbar Antwortobjekte können anwenden
PHP
undDas Obige mag wie Antworten außerhalb des Themas aussehen, aber mir ist nichts anderes bekannt, und deshalb denke ich, dass die Unveränderlichkeitsanforderung ein künstliches Problem ist und eher eine Frage der Präferenz oder des Codierungsstils usw.
quelle
Unveränderliche Objekte haben im Allgemeinen mehrere Vorteile.
Das wichtigste ist, wie einfach es ist, unveränderliche Objekte in parallel ausgeführtem Code zu verwenden. Dies erklärt auch, warum "Unveränderlichkeit im Land von PHP nie wirklich Einzug gehalten hat" .
Zustandskonsistenz ist leichter zu erreichen.
Objekte sind einfach und natürlicher zu bearbeiten.
Das Wesentliche ist, wie stark sich das Objekt während seiner Lebensdauer ändern sollte. Für jede Änderung an einem unveränderlichen Objekt muss eine zusätzliche Instanz erstellt werden, die in Bezug auf den Speicher (und wahrscheinlich auch die CPU-Zyklen) schnell zu teuer sein kann. Dies ist auch der Grund, warum die meisten Programmiersprachen, in denen
string
unveränderlich ist, eine andere Klasse für veränderbare Zeichenfolgen haben, z. B.StringBuilder
in C #, um auf Situationen zu reagieren, in denen Zeichenfolgen aus vielen kleinen Teilen verkettet werden und jeder Teil dynamisch hinzugefügt wird.In einer clientseitigen Bibliothek (Senden einer HTTP-Anforderung und Empfangen einer Antwort) ist es sinnvoll, HTTP-Anforderungen und -Antworten unveränderlich zu machen: Während einige Anforderungen mit einer fließenden Schnittstelle erstellt werden können, ist dies nicht die Hauptverwendung. Die Antwort wird sowieso nicht geändert, daher ist Unveränderlichkeit sinnvoll.
In einer serverseitigen Bibliothek (Empfangen einer HTTP-Anfrage und Senden einer Antwort) bin ich mir nicht sicher, ob die Antwort unveränderlich sein kann. Die Daten selbst können ein Stream sein (der für einige Personen - siehe unten - die Änderung des Antwortobjekts erzwingt), und die Header selbst können während der Ausführung des Skripts "on the fly" hinzugefügt werden, bis die Antwort beginnt an den Kunden gesendet werden.
In beiden Fällen bin ich mir nicht sicher, ob der geringfügige Vorteil der Lesbarkeit den möglichen Mangel an Flexibilität kompensiert, da keine parallele Ausführung erfolgt.
Lesen Sie auch einen vollständigeren Artikel von Evert Pot über PSR-7 . Der Artikel erklärt unter anderem, dass einer der Fälle, in denen eine solche Unveränderlichkeit problematisch ist, lange Antworten sind, die gestreamt werden sollten . Persönlich verstehe ich den Punkt nicht: IMHO verbietet nichts einem unveränderlichen Objekt, einen Stream zu enthalten (zum Beispiel kann ein
FileReader
Objekt unveränderlich sein, selbst wenn es eine Datei liest, die sich im Laufe der Zeit ändern kann). Das Flask-Framework von Python verwendet einen anderen Ansatz, wenn es um große Antworten (oder Antworten, deren Generierung einige Zeit in Anspruch nimmt) geht, indem ein Iterator zurückgegeben wird.quelle