WordPress, per impostazione predefinita, ha una forma di "memorizzazione nella cache degli oggetti" ma la sua durata è solo un singolo caricamento della pagina.
Le opzioni sono in realtà un ottimo esempio di questo. Dai un'occhiata a questa risposta per maggiori informazioni. Il riassunto:
- Inizia una pagina
- Tutte le opzioni sono caricate con una semplice
SELECT option_name, option_value from $wpdb->options
dichiarazione
- Richieste successive per tali opzioni (ad es. Una chiamata per
get_option
non colpire mai il database perché sono archiviate con l'API della cache WP.
Le opzioni "vivono" sempre nel database e sono sempre persistite lì - questa è la loro fonte "canonica". Detto questo, le opzioni vengono caricate nella cache degli oggetti, quindi quando richiedi un'opzione c'è una probabilità del 99% che la richiesta non raggiunga mai il database.
I transitori sono un po 'diversi.
WordPress ti consente di sostituire l'API della cache con un drop-in , un file che viene inserito direttamente nella tua wp-content
cartella. Se si crea il proprio drop in nella cache o si utilizza un plug-in esistente , è possibile mantenere la cache degli oggetti più a lungo di un singolo caricamento della pagina. Quando lo fai, i transitori cambiano un po '.
Diamo un'occhiata alla set_transient
funzione 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
? Se è vero, WordPress utilizza la cache degli oggetti anziché il database per archiviare i transitori. Quindi, come viene impostato su true? È tempo di esplorare come WP imposta la propria API della cache.
Puoi tracciare quasi tutto su wp-load.php
o wp-settings.php
- entrambi sono cruciali per il processo bootstrap di WordPress. Nella nostra cache, ci sono alcune righe rilevanti in wp-settings.php
.
// Start the WordPress object cache, or an external object cache if the drop-in is present.
wp_start_object_cache();
Ricordi quel calo delle cose dall'alto? Diamo uno sguardo a 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' ) );
}
}
Le linee relative alla funzione (quelli che riguardano $_wp_using_ext_object_cache
che altera come transitori sono memorizzati).
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;
}
se object-cache.php
presente nella directory dei contenuti, viene incluso e WP presume che tu stia utilizzando una cache esterna e persistente, impostata $_wp_using_ext_object_cache
su true.
Se stai usando un oggetto esterno, i transitori di cache lo useranno. Il che solleva la questione di quando utilizzare le opzioni rispetto ai transitori.
Semplice. Se hai bisogno che i dati persistano indefinitamente, usa le opzioni. Vengono "memorizzati nella cache", ma le loro fonti canoniche sono il database e non andranno mai via a meno che un utente non lo richieda esplicitamente.
Per i dati che devono essere archiviati per un determinato periodo di tempo, ma non è necessario che persistano oltre un determinato periodo di tempo, utilizzare i transitori. Internamente, WP proverà a utilizzare una cache di oggetti esterna e persistente se può altrimenti i dati andranno nella tabella delle opzioni e verranno spazzati via tramite psuedo-cron di WordPress quando scadono.
Alcune altre preoccupazioni / domande:
- Va bene fare un sacco di chiamate a
get_option
? Probabilmente. Incitano la chiamata a un overhead di funzione, ma probabilmente non colpirà il database. Il caricamento del database è spesso una delle maggiori preoccupazioni nella scalabilità delle applicazioni Web rispetto al lavoro svolto dalla tua lingua preferita per la generazione di una pagina.
- Come faccio a sapere se utilizzare i transitori rispetto all'API della cache? Se si prevede che i dati persistano per un determinato periodo, utilizzare l'API temporanea. Se non importa se i dati persistono (ad es. Non ci vuole molto per calcolare / recuperare i dati, ma non dovrebbe accadere più di una volta per caricamento della pagina) utilizzare l'API della cache.
- Tutte le opzioni sono davvero memorizzate nella cache su ogni pageload? Non necessariamente. Se si chiama
add_option
con l'ultimo argomento facoltativo in quanto no
non vengono caricati automaticamente. Detto questo, una volta recuperati una volta, entrano nella cache e le chiamate successive non colpiranno il database.