WordPress führt standardmäßig eine Form von "Objekt-Caching" durch, die Lebensdauer beträgt jedoch nur eine Seite.
Optionen sind tatsächlich ein wirklich gutes Beispiel dafür. Lesen Sie diese Antwort, um weitere Informationen zu erhalten. Die Zusammenfassung:
- Eine Seite beginnt
- Alle Optionen werden mit einer einfachen
SELECT option_name, option_value from $wpdb->options
Anweisung geladen
- Nachfolgende Anforderungen für diese Optionen (z. B. ein Aufruf,
get_option
der die Datenbank niemals erreicht, weil sie mit der WP-Cache-API gespeichert werden).
Optionen "leben" immer in der Datenbank und werden dort immer beibehalten - das ist ihre "kanonische" Quelle. Das heißt, Optionen werden in den Objekt-Cache geladen. Wenn Sie also eine Option anfordern, besteht eine 99-prozentige Wahrscheinlichkeit, dass die Anforderung niemals die Datenbank erreicht.
Transienten sind etwas anders.
Mit WordPress können Sie die Cache-API durch ein Drop-In ersetzen - eine Datei, die direkt in Ihrem wp-content
Ordner abgelegt wird . Wenn Sie ein eigenes Cache-Drop-In erstellen oder ein vorhandenes Plug-In verwenden , können Sie den Objekt-Cache länger als eine einzelne Seite laden. Wenn Sie dies tun, ändern Sie die Transienten ein wenig.
Werfen wir einen Blick auf die set_transient
Funktion in wp-includes/option.php
.
<?php
/**
* Set/update the value of a transient.
*
* You do not need to serialize values. If the value needs to be serialized, then
* it will be serialized before it is set.
*
* @since 2.8.0
* @package WordPress
* @subpackage Transient
*
* @uses apply_filters() Calls 'pre_set_transient_$transient' hook to allow overwriting the
* transient value to be stored.
* @uses do_action() Calls 'set_transient_$transient' and 'setted_transient' hooks on success.
*
* @param string $transient Transient name. Expected to not be SQL-escaped.
* @param mixed $value Transient value. Expected to not be SQL-escaped.
* @param int $expiration Time until expiration in seconds, default 0
* @return bool False if value was not set and true if value was set.
*/
function set_transient( $transient, $value, $expiration = 0 ) {
global $_wp_using_ext_object_cache;
$value = apply_filters( 'pre_set_transient_' . $transient, $value );
if ( $_wp_using_ext_object_cache ) {
$result = wp_cache_set( $transient, $value, 'transient', $expiration );
} else {
$transient_timeout = '_transient_timeout_' . $transient;
$transient = '_transient_' . $transient;
if ( false === get_option( $transient ) ) {
$autoload = 'yes';
if ( $expiration ) {
$autoload = 'no';
add_option( $transient_timeout, time() + $expiration, '', 'no' );
}
$result = add_option( $transient, $value, '', $autoload );
} else {
if ( $expiration )
update_option( $transient_timeout, time() + $expiration );
$result = update_option( $transient, $value );
}
}
if ( $result ) {
do_action( 'set_transient_' . $transient );
do_action( 'setted_transient', $transient );
}
return $result;
}
Hmmm $_wp_using_ext_object_cache
? Wenn dies zutrifft, verwendet WordPress den Objekt-Cache anstelle der Datenbank, um Transienten zu speichern. Wie wird das nun wahr? Zeit zu erkunden, wie WP seine eigene Cache-API einrichtet.
Sie können fast alles auf wp-load.php
oder wp-settings.php
zurückführen - beides ist entscheidend für den Bootstrap-Prozess von WordPress. In unserem Cache befinden sich einige relevante Zeilen wp-settings.php
.
// Start the WordPress object cache, or an external object cache if the drop-in is present.
wp_start_object_cache();
Erinnerst du dich an das Drop-In-Ding von oben? Werfen wir einen Blick wp_start_object_cache
in wp-includes/load.php
.
<?php
/**
* Starts the WordPress object cache.
*
* If an object-cache.php file exists in the wp-content directory,
* it uses that drop-in as an external object cache.
*
* @access private
* @since 3.0.0
*/
function wp_start_object_cache() {
global $_wp_using_ext_object_cache, $blog_id;
$first_init = false;
if ( ! function_exists( 'wp_cache_init' ) ) {
if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
require_once ( WP_CONTENT_DIR . '/object-cache.php' );
$_wp_using_ext_object_cache = true;
} else {
require_once ( ABSPATH . WPINC . '/cache.php' );
$_wp_using_ext_object_cache = false;
}
$first_init = true;
} else if ( !$_wp_using_ext_object_cache && file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
// Sometimes advanced-cache.php can load object-cache.php before it is loaded here.
// This breaks the function_exists check above and can result in $_wp_using_ext_object_cache
// being set incorrectly. Double check if an external cache exists.
$_wp_using_ext_object_cache = true;
}
// If cache supports reset, reset instead of init if already initialized.
// Reset signals to the cache that global IDs have changed and it may need to update keys
// and cleanup caches.
if ( ! $first_init && function_exists( 'wp_cache_switch_to_blog' ) )
wp_cache_switch_to_blog( $blog_id );
else
wp_cache_init();
if ( function_exists( 'wp_cache_add_global_groups' ) ) {
wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache' ) );
wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
}
}
Die relevanten Zeilen der Funktion (diejenigen, die sich darauf beziehen $_wp_using_ext_object_cache
, ändern, wie Transienten gespeichert werden).
if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
require_once ( WP_CONTENT_DIR . '/object-cache.php' );
$_wp_using_ext_object_cache = true;
} else {
require_once ( ABSPATH . WPINC . '/cache.php' );
$_wp_using_ext_object_cache = false;
}
Wenn object-cache.php
es in Ihrem Inhaltsverzeichnis vorhanden ist, wird es eingeschlossen, und WP geht davon aus, dass Sie einen externen, beständigen Cache verwenden. Es wird $_wp_using_ext_object_cache
auf true gesetzt.
Wenn Sie einen externen Objekt-Cache verwenden, wird dieser von Transienten verwendet. Dies wirft die Frage auf, wann Optionen im Vergleich zu Transienten verwendet werden sollen.
Einfach. Wenn Sie Daten für unbegrenzte Zeit benötigen, verwenden Sie Optionen. Sie werden "zwischengespeichert", aber ihre kanonischen Quellen sind die Datenbank, und sie werden niemals verschwinden, es sei denn, ein Benutzer fordert dies ausdrücklich an.
Verwenden Sie für Daten, die für einen festgelegten Zeitraum gespeichert werden sollen, jedoch nicht länger als eine bestimmte Lebensdauer bestehen müssen, Transienten. Intern wird WP versuchen, einen externen, persistenten Objekt-Cache zu verwenden, wenn dies nicht möglich ist. Andernfalls werden Daten in die Optionstabelle verschoben und bei Ablauf über WordPress 'psuedo-cron gesammelt .
Einige andere Bedenken / Fragen:
- Ist es in Ordnung, eine Menge Anrufe zu tätigen
get_option
? Wahrscheinlich. Sie verursachen den Aufruf eines Funktions-Overheads, der die Datenbank jedoch wahrscheinlich nicht berührt. Das Laden von Datenbanken ist für die Skalierbarkeit von Webanwendungen oft ein größeres Problem als die Arbeit, mit der Ihre Sprache eine Seite erstellt.
- Woher weiß ich, dass ich Transienten im Vergleich zur Cache-API verwenden kann? Wenn Sie davon ausgehen, dass die Daten für einen festgelegten Zeitraum bestehen bleiben, verwenden Sie die transiente API. Wenn es keine Rolle spielt, ob die Daten weiterhin vorhanden sind (z. B. dauert es nicht lange, die Daten zu berechnen / abzurufen, aber es sollte nicht mehr als einmal pro Seitenladevorgang vorkommen), verwenden Sie die Cache-API.
- Werden alle Optionen wirklich auf jeder Seite zwischengespeichert? Nicht unbedingt. Wenn Sie
add_option
mit dem letzten optionalen Argument aufrufen , werden no
sie nicht automatisch geladen. Das heißt, sobald Sie sie einmal abrufen, werden sie in den Cache verschoben, und nachfolgende Aufrufe werden nicht in die Datenbank übernommen.