Im Rahmen meiner Bemühungen, meine Themen für meine Kunden zu beschleunigen, stelle ich mein CSS über eine dynamische PHP-Datei bereit. Am Ende des aufgerufenen Beispiels my_theme_css.php
:
Auf diese Weise kann ich meinem CSS und JavaScript Expiry-Header wie folgt hinzufügen:
<?php
header("Expires: Thu, 31 Dec 2020 20:00:00 GMT");
header('Content-type: text/css');
?>
Ich möchte dem Benutzer dann erlauben, sein eigenes benutzerdefiniertes CSS hinzuzufügen, damit ich Folgendes eingerichtet habe:
<?php
header("Expires: Thu, 31 Dec 2020 20:00:00 GMT");
header('Content-type: text/css');
?>
p{color:blue;}
/** Custom CSS **/
<?php
if(get_theme_mod('my_custom_css') != '') {
$my_custom_css = get_theme_mod('my_custom_css');
echo $my_custom_css;
}
?>
Ich habe dann die entsprechenden Themenoptionen hinzugefügt. Was ich jedoch finde, ist, dass get_theme_mod()
dies aufgrund eines Umfangsproblems nicht funktioniert (wie ich mir vorstellen kann). Irgendwelche Vorschläge, wie man das umgehen kann?
Ich könnte den folgenden Code hinzufügen:
<?php
if(get_theme_mod('my_custom_css') != '') {
$my_custom_css = get_theme_mod('my_custom_css');
echo $my_custom_css;
}
?>
<style></style>
Erwarten Sie, dass innerhalb von Tags im Header und das würde gut funktionieren, ich möchte das CSS nicht inline, sondern in der Haupt-CSS-Datei mit dem Ablauf-Header.
quelle
Antworten:
Hallo @Ash G:
Ich bin nicht 100% gefolgt, wo Sie speziell Probleme hatten, daher bin ich mir nicht sicher, ob ich Ihre Probleme wirklich Punkt für Punkt beantworten kann, aber ich kann erklären, wie dies von Grund auf zu tun ist . Und es sei denn, was Sie tun, ist ein bisschen mehr involviert, als Sie erwähnt haben, dass es ein bisschen mehr Arbeit ist, als Sie erwartet haben, aber es ist immer noch vollständig machbar. Und selbst wenn ich viele Bereiche abdeckte, von denen Sie bereits wissen, dass es eine gute Chance gibt, dass andere mit weniger Wissen oder Erfahrung dies über Google finden und auch davon unterstützt werden.
Bootstrap WordPress mit
/wp-load.php
Das erste, was wir in Ihrer
my_theme_css.php
Datei tun müssen, ist das Booten der Kernbibliotheksfunktionen von WordPress. Die folgende Codezeile wird geladen/wp-load.php
. Es verwendet ,$_SERVER['DOCUMENT_ROOT']
um die Root - Webseite zu finden , so dass Sie Sorge haben nicht darüber , wo Sie speichern diese Datei auf Ihrem Server; Vorausgesetzt, esDOCUMENT_ROOT
ist richtig eingestellt, wie es immer für WordPress sein sollte, dann wird dies WordPress booten:Das ist also der einfache Teil. Als nächstes kommt der schwierige Teil ...
PHP-Skripte müssen die gesamte Caching-Logik verarbeiten
Ich wette, Sie sind hier gestolpert, weil ich es wirklich getan habe, als ich versucht habe, herauszufinden, wie ich Ihre Frage beantworten kann. Wir sind so an die Caching-Details gewöhnt, die vom Apache-Webserver verarbeitet werden, dass wir vergessen oder gar nicht erkennen , dass wir beim Laden von CSS oder JS mit PHP das ganze schwere Heben selbst erledigen müssen .
Sicher, der Ablauf-Header ist möglicherweise alles, was wir brauchen, wenn wir einen Proxy in der Mitte haben, aber wenn die Anfrage an den Webserver gelangt und das PHP-Skript wohl oder übel Inhalte und den Statuscode "Ok" zurückgibt, sind Sie im Wesentlichen gut habe kein Caching.
Rückgabe von "200 Ok" oder "304 Not Modified"
Insbesondere unsere PHP - Datei , dass CSS Bedürfnisse kehrt korrekt auf die reagieren Anfrage vom Browser gesendete Header. Unser PHP-Skript muss den richtigen Statuscode basierend auf dem Inhalt dieser Header zurückgeben. Wenn der Inhalt bereitgestellt werden muss, weil es sich um eine erstmalige Anforderung handelt oder weil der Inhalt abgelaufen ist, sollte das PHP-Skript den gesamten CSS-Inhalt generieren und mit "200 Ok" zurückkehren .
Auf der anderen Seite , wenn wir auf den Cache-bezogenen bestimmen basierend Anfrage - Header , dass der Client - Browser bereits die neueste CSS hat , wir sollten nicht jede CSS zurückzukehren und stattdessen zurückkehren mit einem „304 Not Modified“ . Die zu Codezeilen dafür sind jeweils (natürlich würden Sie niemals beide Zeilen nacheinander verwenden, ich zeige dies hier nur der Einfachheit halber) :
Vier Geschmacksrichtungen des HTTP-Caching
Als nächstes müssen wir uns die verschiedenen Möglichkeiten ansehen, wie HTTP mit dem Caching umgehen kann. Das erste ist, was Sie erwähnen;
Expires
::Expires
Header erwartet ein Datum imFormat( PHP-gmdate()
Funktion )'D, d M Y H:i:s'
mit einem' GMT'
angehängten ( GMT steht für Greenwich Mean Time ). Theoretisch werden der Browser und die nachgeschalteten Proxys zwischengespeichert, bis die angegebene Zeit abgelaufen ist, nach der er gestartet wird die Seite erneut anfordern. Dies ist wahrscheinlich der bekannteste Caching-Header, aber offensichtlich nicht der bevorzugte. Cache-Control ist die bessere . Interessanterweise konnte ich bei meinen Testslocalhost
mit Safari 5.0 unter Mac OS XI den Browser nie dazu bringen, denExpires
Headerzu respektieren. es immerhat die Datei erneut angefordert (wenn jemand dies erklären kann, wäre ich dankbar). Hier ist das Beispiel, das Sie von oben gegeben haben:Cache-Control
Header ist einfacher zu bearbeiten als derExpires
Header, da Sie nur die Anzahl der Sekunden in Sekunden angeben müssen, damitmax-age
Sie kein genaues Datumsformat in Zeichenfolgenform erstellen müssen, das leicht falsch zu verstehen ist . Darüber hinausCache-Control
können verschiedene andere Optionen verwendet werden, z. B. die Möglichkeit, den Clientanzuweisen,den Cache mithilfe diesermustrevalidate
Optionimmer erneut zu validieren,undpublic
wenn Sie das Caching für normalerweise nicht zwischenspeicherbare Anforderungen (dh Anforderungen überHTTPS
)erzwingenund sogar nicht zwischenspeichernmöchten,wenn Sie dies benötigen (Das heißt, Sie möchten möglicherweise ein 1x1-Pixel-Anzeigen-Tracking erzwingen. GIF darf nicht zwischengespeichert werden.) Als obExpires
ich dies auch beim Testennicht zum Laufen bringen könnte( Hilfe?) Das folgende Beispiel wird für einen Zeitraum von 24 Stunden (60 Sekunden x 60 Minuten x 24 Stunden) zwischengespeichert:Last-Modified
Antwort-Header- und das If-Modified-Since
Request-Header-Paar. Diese verwenden ebenfalls dasselbe GMT-Datumsformat wie derExpires
Header, führen jedoch einen Handshake zwischen Client und Server durch. Das PHP-Skript muss einenLast-Modified
Headersenden(den Sie übrigens nur aktualisieren sollten, wenn Ihr Benutzer sein benutzerdefiniertes CSS zuletzt aktualisiert hat). Danach sendet der Browser weiterhin denselben Wert wie einenIf-Modified-Since
Header zurück und es liegt in der Verantwortung des PHP-Skripts Vergleichen Sie den gespeicherten Wert mit dem vom Browser gesendeten. Hier muss das PHP-Skript die Entscheidung treffen, ob a200 Ok
oder abereitgestellt werden soll304 Not Modified
. Hier ist ein Beispiel für das Bereitstellen desLast-Modified
Headers unter Verwendung der aktuellen Zeit (was nicht derFall ist)was wir tun wollen; siehe das spätere Beispiel für das, was wir tatsächlich brauchen):Und so würden Sie die
Last-Modified
vom Browser über denIf-Modified-Since
Header zurückgegebenen Informationen lesen :ETag
Antwortheader und dasIf-None-Match
Anforderungsheaderpaar. DasETag
ist eigentlich nur ein Token, das unser PHP auf einen eindeutigen Wert setzt (normalerweise basierend auf dem aktuellen Datum) und an den Browser sendet und der Browser gibt es zurück. Wenn sich der aktuelle Wert von dem unterscheidet, den der Browser zurückgibt, sollte Ihr PHP-Skript den Inhalt neu200 Ok
generieren,den ein Serversonst nicht generiert und a bereitstellt304 Not Modified
. Hier ist ein Beispiel für die Einstellung einer unterETag
Verwendung der aktuellen Zeit:Und so würden Sie die
ETag
vom Browser über denIf-None-Match
Header zurückgegebenen Informationen lesen :Nachdem wir alles behandelt haben, schauen wir uns den eigentlichen Code an, den wir brauchen:
Bereitstellen der CSS-Datei über
init
undwp_enqueue_style()
Sie haben das nicht gezeigt, aber ich dachte, ich würde es zum Nutzen anderer zeigen. Hier ist der Funktionsaufruf, der WordPress anweist, es
my_theme_css.php
für sein CSS zu verwenden. Dies kann in derfunctions.php
Themendatei oder auf Wunsch auch in einem Plugin gespeichert werden:Es gibt mehrere Punkte zu beachten:
is_admin()
, um das Laden des CSS im Administrator zu vermeiden (es sei denn, Sie möchten das ...),get_theme_mod()
, um das CSS mit einer Standardversion von zu laden1.00
(mehr dazu gleich),get_stylesheet_directory_uri()
, um das richtige Verzeichnis für das aktuelle Thema abzurufen, auch wenn das aktuelle Thema ein untergeordnetes Thema ist.wp_enqueue_style()
um das CSS in die Warteschlange zu stellen, damit WordPress es zum richtigen Zeitpunkt laden kann, wobei'php-powered-css'
ein beliebiger Name später ( falls erforderlich ) als Abhängigkeit verwendet werden kann. Leerarray()
bedeutet, dass dieses CSS keine Abhängigkeiten aufweist ( obwohl dies in der realen Welt häufig der Fall ist eine oder mehrere ) und$version
; Wahrscheinlich die wichtigste, wir empfehlenwp_enqueue_style()
,?ver=1.00
der/my_theme_css.php
URL einen Parameter hinzuzufügen , damit der Browser ihn bei einer Änderung der Version als eine völlig andere URL ansieht (viel mehr dazu in Kürze).Einstellung
$version
undLast-Modified
wann Benutzer CSS aktualisiertAlso hier ist der Trick. Jedes Mal, wenn der Benutzer sein CSS aktualisiert, möchten Sie den Inhalt bereitstellen und nicht warten, bis
2020
der Browser-Cache aller Benutzer eine Zeitüberschreitung aufweist, oder? Hier ist eine Funktion, die in Kombination mit meinem anderen Code dies erreicht. Verwenden Sie jedes Mal, wenn Sie vom Benutzer aktualisiertes CSS speichern, diese Funktion oder Funktionalität, die den folgenden Funktionen ähnelt:Die
set_my_custom_css()
Funktion erhöht die aktuelle Version automatisch um 0,01 (was nur ein beliebiger von mir ausgewählter Inkrementwert war) und setzt das Datum der letzten Änderung auf " Jetzt" und speichert schließlich das neue benutzerdefinierte CSS. Das Aufrufen dieser Funktion ist möglicherweise so einfach (wonew_custom_css
sie wahrscheinlich über einen Benutzer zugewiesen wird, der übermittelt wird,$_POST
anstatt durch Hardcodierung, wie Sie hier sehen) :Das bringt uns zum letzten, wenn auch bedeutenden Schritt:
Generieren des CSS aus dem PHP-Skript
Endlich sehen wir das Fleisch, die eigentliche
my_theme_css.php
Akte. Auf einem hohen Niveau testet es sowohl dieIf-Modifed-Since
gegenüber dem gespeichertenLast-Modified
Wert und dieIf-None-Match
gegen die ,ETag
die von der gespeicherten abgeleitet wurdeLast-Modified
Wert und wenn weder geändert setzt nur den Header304 Not Modifed
und Zweige bis zum Ende.Wenn sich jedoch einer von beiden geändert hat, wird der
Expires
,Cache-Control
.Last-Modified
undEtag
Überschriften sowie ein200 Ok
und, das angibt, dass der Inhaltstyp isttext/css
. Wir brauchen wahrscheinlich nicht alle, aber angesichts der Tatsache, wie schwierig das Caching mit verschiedenen Browsern und Proxys sein kann, schadet es meiner Meinung nach nicht, alle Basen abzudecken. (Und jeder mit mehr Erfahrung mit HTTP-Caching und WordPress meldet sich bitte, wenn ich irgendwelche Nuancen falsch verstanden habe.)Der folgende Code enthält einige weitere Details, aber ich denke, Sie können sie wahrscheinlich selbst herausarbeiten:
Also mit diesen drei Hauptcodebits; 1.) die
add_php_powered_css()
vominit
Hook aufgerufene Funktion , 2.) dieset_my_custom_css()
von welchem Code auch immer aufgerufene Funktion ermöglicht es dem Benutzer, sein benutzerdefiniertes CSS zu aktualisieren, und schließlich 3.) dasmy_theme_css.php
sollten Sie so ziemlich geleckt haben.Weiterführende Literatur
Abgesehen von den bereits verlinkten Artikeln stieß ich auf einige andere Artikel, die ich für sehr nützlich hielt, und dachte mir, ich sollte sie hier verlinken:
Zwischenzuspeichern! Lösen von PHP-Leistungsproblemen - Ein typischer SitePoint- Uber-Artikel; fünf (5) lange Seiten mit Caching und PHP, die sich mit HTTP und anderen Formen des Cachings befassen.
CSS Caching Hack - Das habe ich gemacht,
$version
aber er erklärt ausführlicher als ich.PHP: Howto Control Page Caching - Gute Details zur Verwendung von HTTP-Headern mit PHP.
Epilog:
Aber ich würde das Thema nicht verlassen, ohne abschließende Kommentare abzugeben.
Läuft ab in
2020
? Wahrscheinlich zu extrem.Erstens glaube ich nicht, dass Sie
Expires
das Jahr 2020 festlegen möchten . Browser oder Proxys, die dies respektieren,Expires
werden auch nach vielen CSS-Änderungen nicht erneut angefordert. Es ist besser, etwas Vernünftiges wie 24 Stunden festzulegen (wie ich es in meinem Code getan habe), aber selbst das wird die Benutzer für den Tag frustrieren, an dem Sie Änderungen am fest codierten CSS vornehmen, aber die bereitgestellte Versionsnummer vergessen. Moderation in allen Dingen?Dies könnte sowieso alles übertrieben sein!
Als ich verschiedene Artikel las, um Ihre Frage zu beantworten, stieß ich im Mr. Cache Tutorial selbst, Mark Nottingham, auf Folgendes :
Während all dieser Code, den ich geschrieben habe, cool war und Spaß gemacht hat (ja, das habe ich tatsächlich zugegeben), ist es vielleicht besser, jedes Mal eine statische CSS-Datei zu generieren, wenn der Benutzer stattdessen sein benutzerdefiniertes CSS aktualisiert , und Apache das ganze schwere Heben zu überlassen wie es geboren wurde, um zu tun? Ich sage ja nur...
Hoffe das hilft!
quelle
get_theme_mod()
ist Teil der WordPress-API, ohne dass/wp-load.php
du es nicht bekommst! Und die API ist nicht modular, es ist alles oder nichts. Aber ich werde argumentieren, während Otto im Allgemeinen Recht hat, ist es kein großes Problem, wenn Sie 24 Stunden oder länger mitExpires
oder zwischenspeichernCache-Control
. Und wenn Sie wirklich optimieren möchten, können Sie die Funktion entfernen/wp-load.php
und rohe MySQL-Aufrufe verwenden, um dieget_theme_mod()
Funktion zu ersetzen , wenn Sie möchten. Es ist trivialer Code. Der einzige Nachteil ist, dass die API die Kapselung der Details des Theme-Mod-Speichers bricht.file_get_contents()
und scannen durch/wp-config.php
suchen$table_prefix
undDB_HOST
,DB_NAME
,DB_USER
undDB_PASSWORD
; Das wäre weder schwer zu schreibender Code noch Code mit zu viel Overhead (im Vergleich zu allen/wp-load.php
) zu überlegenden Punkten. :) Und danke für die Auswahl und Abstimmung.Versuchen Sie es wie folgt zu codieren:
Damit sollten Sie alle Probleme mit der
get_theme_mod()
Funktion umgehen können.quelle