Optimisation de la mise en cache pour les templates Smarty

Consultez la formation à Google Analytics de WebRankInfo / Ranking Metrics


Bigb06
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 480
Inscription: 21 Mar 2007

Optimisation de la mise en cache pour les templates Smarty

Message le Mer Aoû 18, 2010 15:54

Bonjour,

Il y a depuis peu pas mal de nouveaux topics sur l'optimisation du chargement des pages, voici ma petite contribution.
La classe présentée, SmartyExtend, permet d'optimiser les performances des sites utilisant Smarty comme système de template. Cette classe gère la mise en cache des templates ainsi que l'ajout des entêtes d'expiration en accord avec le temps de mise en cache demandé.



La classe:

Code: Tout sélectionner
<?php

/**
* Project:     SmartyExtend: permet d'améliorer la mise en cache des templates Smarty
* File:        SmartyExtend.php
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* @author Nicolas Chevallier <nicolas.chevallier@b2b-net.com>
* @version 1.0
*/


class SmartyExtend extends Smarty{
   
    public function __construct($tpl=null,$cache_time=0,$id=null)
    {
      parent::__construct();

      // si on ne veut pas utiliser de cache
      if(is_null($tpl) || $cache_time == 0){
         $this->caching = 0;
      }
      else{
         // si on veut renouveller le fichier en cache
         if(isset($_GET['clearcache']) && $_GET['clearcache'] == 'true'){
            if($id!= null){
               $this->clear_cache ($tpl,$id);
            }else{
               $this->clear_cache($tpl);
            }
         }
         $this->caching = 2;
         $this->cache_lifetime = $cache_time;
         // Si le template est en cache, on l'affiche et on quitte
         if($id!= null){
            if($this->is_cached($tpl,$id)){
               $this -> display( $tpl,$id_original);
               exit();
            }
         }
         else{
            if($this->is_cached($tpl)){
               $this -> display( $tpl );
               exit();
            }         
         }
      }   
      //$this -> debugging = false;
      //$this -> debugging_ctrl = (DEBUG_MODE == true) ? 'URL' : 'NONE';
    }


   // surcharge de la fonction fetch pour améliorer les performances
   // gestion des headers Expires et Cache control
    function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
    {
       if(isset($_GET['next'])){
         $cache_id = $cache_id.$_GET['next'];
      }
        static $_cache_info = array();
       
        $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
               ? $this->error_reporting : error_reporting() & ~E_NOTICE);

        if (!$this->debugging && $this->debugging_ctrl == 'URL') {
            $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
            if (@strstr($_query_string, $this->_smarty_debug_id)) {
                if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
                    // enable debugging for this browser session
                    @setcookie('SMARTY_DEBUG', true);
                    $this->debugging = true;
                } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
                    // disable debugging for this browser session
                    @setcookie('SMARTY_DEBUG', false);
                    $this->debugging = false;
                } else {
                    // enable debugging for this page
                    $this->debugging = true;
                }
            } else {
                $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
            }
        }

        if ($this->debugging) {
            // capture time for debugging info
            $_params = array();
            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
            $_debug_start_time = smarty_core_get_microtime($_params, $this);
            $this->_smarty_debug_info[] = array('type'      => 'template',
                                                'filename'  => $resource_name,
                                                'depth'     => 0);
            $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
        }

        if (!isset($compile_id)) {
            $compile_id = $this->compile_id;
        }

        $this->_compile_id = $compile_id;
        $this->_inclusion_depth = 0;

        if ($this->caching) {
            // save old cache_info, initialize cache_info
            array_push($_cache_info, $this->_cache_info);
            $this->_cache_info = array();
            $_params = array(
                'tpl_file' => $resource_name,
                'cache_id' => $cache_id,
                'compile_id' => $compile_id,
                'results' => null
            );
            require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
            if (smarty_core_read_cache_file($_params, $this)) {
                $_smarty_results = $_params['results'];
                if (!empty($this->_cache_info['insert_tags'])) {
                    $_params = array('plugins' => $this->_cache_info['insert_tags']);
                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
                    smarty_core_load_plugins($_params, $this);
                    $_params = array('results' => $_smarty_results);
                    require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
                    $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
                }
                if (!empty($this->_cache_info['cache_serials'])) {
                    $_params = array('results' => $_smarty_results);
                    require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
                    $_smarty_results = smarty_core_process_compiled_include($_params, $this);
                }


                if ($display) {
                    if ($this->debugging)
                    {
                        // capture time for debugging info
                        $_params = array();
                        require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
                        $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
                        require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
                        $_smarty_results .= smarty_core_display_debug_console($_params, $this);
                    }
                    if ($this->cache_modified_check) {
                        $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
                        $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
                        $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
                        if (@count($this->_cache_info['insert_tags']) == 0
                            && !$this->_cache_serials
                            && $_gmt_mtime == $_last_modified_date) {
                            if (php_sapi_name()=='cgi')
                                header('Status: 304 Not Modified');
                            else
                                header('HTTP/1.1 304 Not Modified');
                        } else {
                           // ajout de headers, le fichier est déja en cache
                           // expires affecté à date de modification + temps de mise en cache
                           header('Expires: ' . gmdate('D, d M Y H:i:s',$this->_cache_info['timestamp']+$this->cache_lifetime) . ' GMT');
                     //header('Cache-Control: max-age='.$this->cache_lifetime - ($this->_cache_info['timestamp'] - time()));
                            header('Last-Modified: '.$_gmt_mtime);
                            echo $_smarty_results;
                        }
                    } else {
                            echo $_smarty_results;
                    }
                    error_reporting($_smarty_old_error_level);
                    // restore initial cache_info
                    $this->_cache_info = array_pop($_cache_info);
                    return true;
                } else {
                    error_reporting($_smarty_old_error_level);
                    // restore initial cache_info
                    $this->_cache_info = array_pop($_cache_info);
                    return $_smarty_results;
                }
            } // pas de fichier cache present
             else {
                $this->_cache_info['template'][$resource_name] = true;
                if ($this->cache_modified_check && $display) {
                    // ajout de headers, on vient de créer le fichier
                    // expires affecté now + à temps de mise en cache
                    header('Expires: ' . gmdate('D, d M Y H:i:s',time()+$this->cache_lifetime) . ' GMT');
               //header('Cache-Control: max-age='.$this->cache_lifetime);
                    header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
                }
            }
        }

        // load filters that are marked as autoload
        if (count($this->autoload_filters)) {
            foreach ($this->autoload_filters as $_filter_type => $_filters) {
                foreach ($_filters as $_filter) {
                    $this->load_filter($_filter_type, $_filter);
                }
            }
        }

        $_smarty_compile_path = $this->_get_compile_path($resource_name);

        // if we just need to display the results, don't perform output
        // buffering - for speed
        $_cache_including = $this->_cache_including;
        $this->_cache_including = false;
        if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
            {
                include($_smarty_compile_path);
            }
        } else {
            ob_start();
            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
            {
                include($_smarty_compile_path);
            }
            $_smarty_results = ob_get_contents();
            ob_end_clean();

            foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
                $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
            }
        }

        if ($this->caching) {
            $_params = array('tpl_file' => $resource_name,
                        'cache_id' => $cache_id,
                        'compile_id' => $compile_id,
                        'results' => $_smarty_results);
            require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
            smarty_core_write_cache_file($_params, $this);
            require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
            $_smarty_results = smarty_core_process_cached_inserts($_params, $this);

            if ($this->_cache_serials) {
                // strip nocache-tags from output
                $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
                                                ,''
                                                ,$_smarty_results);
            }
            // restore initial cache_info
            $this->_cache_info = array_pop($_cache_info);
        }
        $this->_cache_including = $_cache_including;

        if ($display) {
            if (isset($_smarty_results)) { echo $_smarty_results; }
            if ($this->debugging) {
                // capture time for debugging info
                $_params = array();
                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
                $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
                require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
                echo smarty_core_display_debug_console($_params, $this);
            }
            error_reporting($_smarty_old_error_level);
            return;
        } else {
            error_reporting($_smarty_old_error_level);
            if (isset($_smarty_results)) { return $_smarty_results; }
        }
    }
}//end of class
?>



Un exemple d'utilisation :
On prend l'exemple d'une fiche avec un paramètre id
Code: Tout sélectionner
<?php
// chargements des bibliothèques et inclusions...
$smarty = new SmartyExtend('template.tpl',24*60*60,$_GET["id"]);// mise en cache 24h

// Le code ci dessous ne sera éxécuté que si le template n'est pas en cache

// affichage et stockage du template une fois les traitements effectués
$content = $smarty -> fetch( 'template.tpl',$_GET["id"]);
echo $content;

?>


Dans cet exemple la page ne sera générée qu'une fois toutes les 24h, et la date d'expiration correspondra à la fin de la mise en cache. Cela permet à GoogleBot de connaître la date de prochain passage optimale, et aux visiteurs de garder en cache le fichier html (plus aucune requête ne sera nécessaire si les Etags sont désactivés). Pour regénérer une fiche il suffit d'ajouter ?clearcache=true à la fin de l'url.


spout
WRInaute accro
WRInaute accro
 
Messages: 4101
Inscription: 14 Mai 2003

Re: Optimisation de la mise en cache pour les templates Smarty

Message le Mer Aoû 18, 2010 17:38

Ça existe tjs Smarty ? :mrgreen:

http://www.massassi.com/php/articles/template_engines/
In short, the point of template engines should be to separate your business logic from your presentation logic, not separate your PHP code from your HTML code.

http://www.m4d3l-network.com/developpement/php/dites-non-a-smarty/

Sorry, je la ramène tjs avec le lien massassi.com ^^


Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Formation recommandée sur ce thème :

Formation Google Analytics : en 2 jours, apprenez comment exploiter l'essentiel des possibilités de l'outil de mesure d'audience de Google. Formation animée par les experts Google Analytics de Ranking Metrics.

Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités