WordPress, par défaut, fait une forme de "mise en cache d'objet" mais sa durée de vie n'est qu'une charge de page unique.
Les options en sont un très bon exemple. Consultez cette réponse pour plus d'informations. Le résumé:
- Une page démarre
- Toutes les options sont chargées avec une simple
SELECT option_name, option_value from $wpdb->options
déclaration
- Demandes ultérieures pour ces options (par exemple, un appel pour
get_option
ne jamais toucher la base de données car elles sont stockées avec l'API de cache WP.
Les options sont toujours "actives" dans la base de données et y sont toujours persistantes - c'est leur source "canonique". Cela dit, les options sont chargées dans le cache d'objets, donc lorsque vous demandez une option, il y a 99% de chances que la demande n'atteigne jamais la base de données.
Les transitoires sont un peu différents.
WordPress vous permet de remplacer l'API de cache par un drop-in - un fichier qui est placé directement dans votre wp-content
dossier. Si vous créez votre propre dépôt de cache ou utilisez un plugin existant , vous pouvez faire en sorte que le cache d'objets persiste plus longtemps qu'un chargement de page unique. Lorsque vous faites cela, transitoires, changez un peu.
Jetons un coup d'œil à la set_transient
fonction dans 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
? Si c'est vrai, WordPress utilise le cache d'objets au lieu de la base de données pour stocker les transitoires. Alors, comment cela devient-il vrai? Il est temps d'explorer comment WP configure sa propre API de cache.
Vous pouvez tracer presque tout vers wp-load.php
ou wp-settings.php
- qui sont tous deux cruciaux pour le processus d'amorçage de WordPress. Dans notre cache, il y a quelques lignes pertinentes wp-settings.php
.
// Start the WordPress object cache, or an external object cache if the drop-in is present.
wp_start_object_cache();
Rappelez-vous cette chute d'en haut? Jetons un coup d' oeil à wp_start_object_cache
en 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' ) );
}
}
Les lignes pertinentes de la fonction (celles qui s'y rapportent $_wp_using_ext_object_cache
modifient la façon dont les transitoires sont stockés).
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;
}
s'il object-cache.php
existe dans votre répertoire de contenu, il est inclus et WP suppose que vous utilisez un cache persistant externe - il est défini $_wp_using_ext_object_cache
sur true.
Si vous utilisez un cache d'objets externe, les transitoires l'utiliseront. Ce qui soulève la question de savoir quand utiliser les options par rapport aux transitoires.
Simple. Si vous avez besoin que les données persistent indéfiniment, utilisez les options. Ils sont "mis en cache", mais leurs sources canoniques sont la base de données et ils ne disparaîtront jamais à moins qu'un utilisateur ne le demande explicitement.
Pour les données qui doivent être stockées pendant une durée définie, mais qui n'ont pas besoin de persister au-delà d'une durée de vie spécifiée, utiliser des transitoires. En interne, WP essaiera d'utiliser un cache d'objets persistant externe s'il le peut, sinon les données iront dans le tableau des options et récupèreront les ordures via psuedo-cron de WordPress à leur expiration.
Quelques autres préoccupations / questions:
- Est-il acceptable de faire une tonne d'appels à
get_option
? Probablement. Ils encourent l'appel à une surcharge de fonction, mais il n'atteindra probablement pas la base de données. La charge de la base de données est souvent une préoccupation plus importante dans l'évolutivité des applications Web que le travail que la langue de votre choix génère pour une page.
- Comment savoir comment utiliser les transitoires par rapport à l'API de cache? Si vous vous attendez à ce que les données persistent pendant une période définie, utilisez l'API transitoire. Si cela n'a pas d'importance si les données persistent (par exemple, il ne faut pas longtemps pour calculer / récupérer les données, mais cela ne devrait pas se produire plus d'une fois par chargement de page), utilisez l'API de cache.
- Toutes les options sont-elles vraiment mises en cache sur chaque chargement de page? Pas nécessairement. Si vous appelez
add_option
avec son dernier argument facultatif car no
ils ne sont pas chargés automatiquement. Cela dit, une fois que vous les avez récupérés une fois, ils vont dans le cache et les appels suivants n'atteindront pas la base de données.