4.3. Frontends Zend_Cache

4.3.1. Zend_Cache_Core

4.3.1.1. Introduction

Zend_Cache_Core est un frontend spécial parce qu'il est le coeur du module. C'est le frontend de cache générique qui est étendu par les autres classes.

[Note] Note

Tous les frontends héritent de Zend_Cache_Core ainsi ses méthodes et options (décrites ci-dessous) seront aussi disponibles dans les autres frontends, cependant ils ne sont pas documentés ici.

4.3.1.2. Options disponibles

Ces options sont passées à la méthode de fabrique comme montrées dans les exemples précédents.

Tableau 4.1. Otions disponibles

Option Type de données Valeur par défaut Description
caching booléen true active / désactive le cache (peut-être très utile pour le débogage de scripts en cache)
lifetime entier 3600 temps de vie (en secondes) du cache, si défini à null, le cache est valide indéfiniment
logging booléen false si défini à true, le logging par Zend_Log est activé (mais le système sera plus lent)
write_control booléen true Active / désactive le contrôle d'écriture (le cache est lu juste après l'écriture pour détecter des entrées corrompues), activer 'writeControl' va ralentir un petit peu l'écriture du cache, mais pas la lecture (il peut détecter des fichiers de cache corrompus, mais ceci n'est pas un contrôle parfait).
automatic_serialization booléen false Active / désactive la sérialisation automatique, il peut être utilisé pour enregistrer directement des données qui ne sont pas des chaînes de caractères (mais c'est plus lent).
automatic_cleaning_factor int 0 Active / désactive le nettoyage automatique (garbage collector): 0 signifie aucun nettoyage automatique de cache, 1 signifie un nettoyage systèmatique du cache et x > 1 signifie le nettoyage aléatoire 1 fois toute les x écritures.

4.3.1.3. Exemples

Un exemple est donné dans le manuel, tout au début.

Si vous stocker uniquement des chaînes de caractères dans le cache (parce qu'avec l'option "automatic_serialization", il est possible de stocker des booléens), vous pouvez utiliser une construction plus compact comme :

<?php
// nous avons déjà $cache

$id = 'myBigLoop'; // id de cache de "ce que l'on veut cacher"

if (!($data = $cache->get($id))) {
    // cache manquant

    $data = '';
    for ($i = 0; $i < 10000; $i++) {
        $data = $data . $i;
    }

    $cache->save($data);

}

// [...] fait quelque chose avec $data (affichage, passage ailleurs, etc, etc)
?>       

Si vous voulez cacher des blocs multiples ou des instances de données, l'idée reste la même:

<?php
// on s'assure que l'on utilise des identifiant uniques
$id1 = 'foo';
$id2 = 'bar';

// block 1
if (!($data = $cache->get($id1))) {
    // cache missed

    $data = '';
    for ($i=0;$i<10000;$i++) {
        $data = $data . $i;
    }

    $cache->save($data);

}
echo($data);

// ceci n'est pas affecté par la mise en cache
echo('NEVER CACHED! ');

// block 2
if (!($data = $cache->get($id2))) {
    // cache missed

    $data = '';
    for ($i=0;$i<10000;$i++) {
        $data = $data . '!';
    }

    $cache->save($data);

}
echo($data);
?>       

4.3.2. Zend_Cache_Frontend_Output

4.3.2.1. Introduction

Zend_Cache_Frontend_Output est un frontend capturant la sortie. Il utilise la bufferisation de sortie de PHP pour capturer tout ce qui passe entre les méthodes start() et end() .

4.3.2.2. Options disponibles

Ce frontend n'a pas d'options spécifiques autres que celles de Zend_Cache_Core.

4.3.2.3. Exemples

Un exemple est donnée dans le manuel, tout au début. Le voici avec des changements mineurs:

<?php
// s'il y a un cache manquant, la bufferisation de sortie est lancée
if (!$cache->start('mypage')) {

    // affiche tout comme d'habitude
    echo 'Hello world! ';
    echo 'This is cached ('.time().') ';

    $cache->end(); // affiche ce qu'il y a dans le buffer
}

echo 'This is never cached ('.time().').';
?>       

Utiliser cette forme est assez simple pour définir une mise de cache de sortie dans vos projets déjà en production, avec peu de refactorisation de code.

4.3.3. Zend_Cache_Frontend_Function

4.3.3.1. Introduction

Zend_Cache_Frontend_Function met en cache les résultats des appels de fonction. Elle a une seule méthode principale appelée call() qui prend un nom de fonction et des paramètres pour l'appel dans un tableau.

4.3.3.2. Options disponibles

Tableau 4.2. Options disponibles

Option Type de données Valeur par défaut Description
cache_by_default booléen true si true, les appels de fonction seront mis en cache par défaut
cached_functions array   les noms de fonctions seront toujours mis en cache
non_cached_functions array   les noms de fonctions ne doivent jamais être mis en cache

4.3.3.3. Exemples

Utiliser la fonction call() est la même chose qu'utiliser call_user_func_array() en PHP:

<?php
$cache->call('veryExpensiveFunc', $params);

# $params est dans un tableau
# par exemple, pour appeler (avec mise en cache) veryExpensiveFunc(1, 'foo', 'bar')
#vous devriez utiliser
$cache->call('veryExpensiveFunc', array(1, 'foo', 'bar'))
?>       

Zend_Cache_Frontend_Function est assez intelligente pour mettre en cache la valeur de retour de la fonction, aisi que sa sortie interne.

[Note] Note

Vous pouvez passer n'importe quelle fonction utilisateur à l'exception de array(), echo(), empty(), eval(), exit(), isset(), list(), print() et unset().

4.3.4. Zend_Cache_Frontend_Class

4.3.4.1. Introduction

Zend_Cache_Frontend_Class est différent de Zend_Cache_Frontend_Function parce qu'elle permet de mettre en cache les objets et les méthodes statiques.

4.3.4.2. Options disponibles

Tableau 4.3. Options disponibles

Option Type de données Valeur par défaut Description
cached_entity (required) mixed   si défini avec un nom de classe, nous allons mettre en cache une claisse abstraite et utiliser uniquement les appels statiques; si défini avec un objet, nous allons mettre en cache les méthodes de cet objet.
cache_by_default booléen true si true, les appels vont être caché par défault
cached_methods array   les noms des méthodes qui seront toujours mis en cache
non_cached_methods array   les noms des méthodes qui ne doivent jamais être mises en cache

4.3.4.3. Exemples

Par exemple, pour mettre en cache des appels statiques :

<?php
class test {

    # Méthode statique
    public static function foobar($param1, $param2) {
        echo "foobar_output($param1, $param2)";
        return "foobar_return($param1, $param2)";
    }

}

// [...]
$frontendOptions = array(
    'cached_entity' => 'test' // Le nom de la classe
);
// [...]

# l'appel caché
$res = $cache->foobar('1', '2');
?>           

Pour mettre en cache des appels classiques aux méthodes :

<?php
class test {

    private $_string = 'hello !';

    public function foobar2($param1, $param2) {
        echo($this->_string);
        echo "foobar2_output($param1, $param2)";
        return "foobar2_return($param1, $param2)";
    }

}

// [...]
$frontendOptions = array(
    'cached_entity' => new test() // Une instance de la classe
);
// [...]

# L'appel mis en cache
$res = $cache->foobar2('1', '2');
?>           

4.3.5. Zend_Cache_Frontend_File

4.3.5.1. Introduction

Zend_Cache_Frontend_File est un frontend piloté par la modification d'un "fichier maître". C'est vraiment intéressant, par exemple, dans les problématiques de configuration ou de templates.

Pour l'instant, vous avez un fichier de configuration XML qui est parsé par une fonction qui retourne un "objet config" (comme avec Zend_Config). Avec Zend_Cache_Frontend_File, vous pouvez stocker l'objet config dans le cache (pour éviter de parser le fichier de config XML chaque fois) mais avec une sorte de forte dépendance au fichier maître. Ainsi si le fichier XML de config est modifié, le cache est immédiatement invalide.

4.3.5.2. Options disponibles

Tableau 4.4. Options disponibles

Option Type de données Valeur par défaut Description
master_file (mandatory) string le chemin complet et le nom du fichier maître

4.3.5.3. Exemples

L'utilisation de ce frontend est la même que celle deZend_Cache_Core. Il n'y a pas besoin d'exemple spéifique - la seule chose à faire est de définir le masterFile lors de l'utilisation de la fabrique.

4.3.6. Zend_Cache_Frontend_Page

4.3.6.1. Introduction

Zend_Cache_Frontend_Page est comme Zend_Cache_Frontend_Output mais créé pour une page complète. Il est impossible d'utiliser Zend_Cache_Frontend_Page pour mettre en cacher un bloc unique.

D'un autre côté, la "cache id", est calculé automatiquement avec $_SERVER['REQUEST_URI'] et (en fonction des options) $_GET, $_POST, $_SESSION, $_COOKIE, $_FILES. De plus, vous avez seulement une méthode pour appeler (start()) parce que l'appel à end() est totalement automatique lorsque la page est terminé.

Pour le moment, ceci n'est pas implémenté mais nous prévoyons d'ajouter un système de condition HTTP pour économiser de la bande passant (le système enverra une entête HTTP 304 Not Modified si le cache est trouvé, et si le navigateur a déjà la bonne version).

4.3.6.2. Options disponibles (pour ce frontend dans la fabrique Zend_Cache)

Tableau 4.5. Options disponibles

Option Type de données Valeur par défaut Description
http_conditional booléen false utilisez le système httpConditionnal ou pas (pas encore implémenté)
debug_header booléen false si true, un text de débogage est ajouté avant chaque page de cache
default_options array array(...see below...) un tableau associatif d'options par défaut:
  • (booléen, true par défaut) cache : le cache est activé si true

  • (booléen, false par défaut) cache_with_get_variables : si true, le cache est toujours activé même s'il y a des variables dans le tableau $_GET

  • (booléen, false par défaut) cache_with_post_variables : si true, le cache est toujours activé même s'il y a des variables dans le tableau $_POST

  • (booléen, false par défaut) cache_with_session_variables : si true, le cache est toujours activé s'il y a des variables dans le tableau $_SESSION

  • (booléen, false par défaut) cache_with_files_variables : si true, le cache est toujours activé s'il y a des variables dans le tableau $_FILES

  • (booléen, false par défaut) cache_with_cookie_variables : si true, le cache est toujours activé s'il y a des variables dans leétableau $_COOKIE

  • (booléen, true par défaut) make_id_with_get_variables : si true, l'identifiant du cache sera dépendant du contenu du tableau $_GET

  • (booléen, true par défaut) make_id_with_post_variables : si true, l'identifiant du cache sera dépendant du contenu du tableau $_POST

  • (booléen, true par défaut) make_id_with_session_variables : si true, l'identifiant du cache sera dépendant du contenu du tableau $_SESSION

  • (booléen, true par défaut) make_id_with_files_variables : si true, l'identifiant du cache sera dépendant du contenu du tableau $_FILES

  • (booléen, true par défaut) make_id_with_cookie_variables : si true, l'identifiant du cache sera dépendant du contenu du tableau $_COOKIE

regexps array array() un tableau associatif pour définir les options, uniquement pour certaines REQUEST_URI, les clés sont des regex PCRE, les valeurs sont des tableaus associatifs avec des options spécifiques pour définir si les regexs correspondent dans $_SERVER['REQUEST_URI'] (voir les options par défaut pour la liste des options disponibles) ; si plusieurs regex correspondent à un $_SERVER['REQUEST_URI'], seul la dernière sera utilisée.

4.3.6.3. Exemples

L'utilisation de Zend_Cache_Frontend_Page est vraiment trivial :

<?php
// [...] // require, configuration et factory

$cache->start();
// si le cache est trouvé, le résultat est envoyé au navigateur et le script s'arrête là

// reste de la page ...
?>           

un exemple plus complexe qui montre un moyen pour obtenir une gestion centralisée du cache dans un fichier d'amorçage (pour utiliser avec Zend_Controller par exemple)

<?php
// vous devriez éviter de mettre trop de lignes avant la section de cache
// [...] par exemple, pour des performances optimales, "require_once" ou "Zend_Loader::loadClass" devrait être
// [...] après la section de cache

require_once 'Zend/Cache.php';

$frontendOptions = array(
   'lifetime' => 7200,
   'debug_header' => true, // pour le déboguage
   'regexps' => array(
       '^/$' => array('cache' => true),           // met en cache la totalité d'IndexController
       '^/index/' => array('cache' => true),      // met en cache la totalité d'IndexController
       '^/article/' => array('cache' => false),   // nous ne mettons pas en cache l'ArticleController...
       '^/article/view/' => array(                // ...mais nous mettons en cache l'action "view"
           'cache' => true,                       // de cet ArticleController
           'cache_with_post_variables' => true,   // et nous mettons en cache même lorsqu'il y a des variables dans $_POST
           'make_id_with_post_variables' => true, // (mais le cache sera dépendent du tableau $_POST)
       )
   )
);
$backendOptions = array(
    'cache_dir' => '/tmp/'
);

// obtenir un objet Zend_Cache_Frontend_Page
$cache = Zend_Cache::factory('Page', 'File', $frontendOptions, $backendOptions);

$cache->start();
// si nous trouvons un cache, le résultat est envoyé au navigateur, et le script s'arrête là

// [...] la fin du fichier de démarrage (ces lignes ne seront pas exécutée si on trouve un cache)
?>