2012-05-15 4 views
14

Ich denke, meine Frage scheint ziemlich lässig, aber ertragen Sie mit mir, wie es interessant wird (zumindest für mich :)).Caching HTTP-Antworten, wenn sie dynamisch von PHP erstellt werden

Betrachten Sie eine PHP-Seite, deren Zweck es ist, eine angeforderte Datei aus dem Dateisystem zu lesen und sie als Antwort auszugeben. Jetzt ist die Frage, wie Cache für diese Seite aktivieren? Es muss darauf hingewiesen werden, dass die Dateien sehr groß sein können und der Cache es ermöglicht, den Client davor zu bewahren, den gleichen Inhalt immer wieder herunterzuladen.

Die ideale Strategie wäre die Verwendung der "If-None-Match" -Anfragekopfzeile und der "ETag" -Antwortkopfzeile, um ein Reverse-Proxy-Cachesystem zu implementieren. Obwohl ich soweit weiß, bin ich mir nicht sicher, ob das möglich ist oder was ich als Antwort zurückgeben soll, um diese Technik zu implementieren!

+0

Kühles Auge. Immer noch kein Spiel für mich. –

+0

Sei dir nicht so sicher, der Besitzer dieses Auges ist jetzt Juubi's Jinchuuriki! – Mehran

+0

Für jetzt, aber meine Trumpfkarte wurde noch nicht bekannt gegeben. Lass uns diesen Chat über [Anime & Manga Chat] fortsetzen (http://chat.stackexchange.com/rooms/6697/anime-and-manga). Um diesen Thread nicht zu verwirren. –

Antwort

25

Serving große oder viele Hilfsdateien mit PHP ist nicht genau das, wofür es gemacht ist.

Betrachten Sie stattdessen X-accel für nginx, X-Sendfile für Lighttpd oder mod_xsendfile für Apache.

Die anfängliche Anfrage wird von PHP gehandhabt, aber sobald die Download-Datei bestimmt wurde, legt sie ein paar Header fest, um anzuzeigen, dass der Server die Datei senden soll, worauf der PHP-Prozess für etwas anderes freigegeben wird.

Sie können dann den Webserver verwenden, um das Caching für Sie zu konfigurieren.

Static generierte Inhalte

Wenn Ihr Inhalt von PHP generiert und besonders teuer zu erstellen, können Sie die Ausgabe in eine lokale Datei schreiben konnte und das obige Verfahren erneut anwenden.

Wenn Sie sich nicht in eine lokale Datei schreiben oder nicht wollen, können Sie HTTP-Response-Header verwenden Caching steuern:

Expires: <absolute date in the future> 
Cache-Control: public, max-age=<relative time in seconds since request> 

Dies wird Kunden führen die Seiteninhalte zwischenzuspeichern, bis sie abgelaufen ist oder wenn ein Benutzer das erneute Laden einer Seite erzwingt (z. B. F5 drücken).

Dynamisch generierte Inhalte

Für dynamische Inhalte, die Sie der Browser möchten Sie jedes Mal, ping, aber nur die Seiteninhalte senden, wenn es etwas Neues gibt. Sie können dies erreichen, indem ein paar anderen Antwort-Header Einstellung:

ETag: <hash of the contents> 
Last-Modified: <absolute date of last contents change> 

Wenn der Browser wieder Ihren Skript Pings, werden sie die folgenden Request-Header hinzufügen, jeweils:

If-None-Match: <hash of the contents that you sent last time> 
If-Modified-Since: <absolute date of last contents change> 

Die ETag meist verwendet wird, zu reduzieren, Netzwerkverkehr als in einigen Fällen, um den Inhalt Hash zu kennen, müssen Sie es zuerst berechnen.

Die ist am einfachsten anzuwenden, wenn Sie lokale Dateicaches haben (Dateien haben ein Änderungsdatum). Eine einfache Bedingung macht es Arbeit:

if (!file_exists('cache.txt') || 
    filemtime('cache.txt') > strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { 
    // update cache file and send back contents as usual (+ cache headers) 
} else { 
    header('HTTP/1.0 304 Not modified'); 
} 

Wenn Sie nicht Datei-Caches tun können, haben Sie noch ETag verwenden können, um zu bestimmen, ob der Inhalt inzwischen verändert haben.

+0

Es ist mein schlechtes, dass ich vergessen habe zu erwähnen, die Beseitigung von PHP ist unmöglich. Es könnte eine komplizierte Logik innerhalb des PHP geben. – Mehran

+0

@MehranZiadloo Vielleicht hast du meine Antwort nicht bekommen, ich habe es umformuliert. –

+0

Auch wenn Ihr Update Ihren Standpunkt klargestellt hat, aber ich fürchte, es ist immer noch unmöglich, PHP zu eliminieren, da der Inhalt manchmal generiert und nicht geladen wird. Danke trotzdem. – Mehran

Verwandte Themen