Стандартный обработчик кэширования в Smarty

The employer

Новичок
Стандартный обработчик кэширования в Smarty

Возможно, кому-то пригодится.

Как-то помог одному товарищу разобраться вот с каким вопросом:
> Есть ли в нем самом (или есть ли возможность приделать к нему) механизм блокировки, дабы предотвратить ситуации, когда второй запрос страницы приходит
> до завершения генерации кэша, и в итоге процесс выборки данных повторяется заново?

Есть штатная возможность приделать к нему собственный механизм кэширования, кторый может в том числе содержать реализацию блокировок.

Делается это при помощи Cache Handler Function: http://www.smarty.net/manual/en/section.template.cache.handler.func.php

Далее.

Можно сделать навеску над стандартным обработчиком.

Собственно, стандартный обработчик в виде целостной функции будет выглядеть так (кстати, не понимаю почему пацаны из смарти не сделали такой рефакторинг):

PHP:
function standard_cache_handler(
    $action
  , &$smarty
  , &$cache_content
  , $tpl_file   = null
  , $cache_id   = null
  , $compile_id = null
  , $exp_time   = null
) {

    switch( $action ) {

        case "read":

            $_auto_id      = $smarty->_get_auto_id( $cache_id, $compile_id );
            $_cache_file   = $smarty->_get_auto_filename( $smarty->cache_dir, $tpl_file, $_auto_id );
            $cache_content = $smarty->_read_file( $_cache_file );
            return true;

        case "write":

            if( !@is_writable( $smarty->cache_dir ) ) {
                // cache_dir not writable, see if it exists
                if( !@is_dir( $smarty->cache_dir ) ) {
                    $smarty->trigger_error(
                        'the $cache_dir \'' . $smarty->cache_dir
                      . '\' does not exist, or is not a directory.', E_USER_ERROR
                    );
                    return false;
                }
                $smarty->trigger_error(
                    'unable to write to $cache_dir \'' . realpath($smarty->cache_dir)
                  . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR
                );
                return false;
            }

            $_auto_id    = $smarty->_get_auto_id( $cache_id, $compile_id );
            $_cache_file = $smarty->_get_auto_filename( $smarty->cache_dir, $tpl_file, $_auto_id );
            $_params     = array( 'filename' => $_cache_file, 'contents' => $cache_content, 'create_dirs' => true );
            require_once( SMARTY_CORE_DIR . 'core.write_file.php' );
            smarty_core_write_file( $_params, $smarty );

            return true;


        case "clear":

            $_auto_id = $smarty->_get_auto_id( $cache_id, $compile_id );
            $_params  = array(
                'auto_base'   => $smarty->cache_dir
              , 'auto_source' => $tpl_file
              , 'auto_id'     => $_auto_id
              , 'exp_time'    => $exp_time
            );
            require_once( SMARTY_CORE_DIR . 'core.rm_auto.php' );
            return smarty_core_rm_auto( $_params, $smarty );

        default:
            $smarty->_trigger_error_msg( "cache_handler: unknown action \"$action\"" );
            return false;

    }

}
Теперь в этот обработчик ты можешь вставить (в ветки read и write) любую блокировку, какую захочешь.

> Правильно ли я понимаю, что достаточно вставить в ветку read что-то типа установки семафора, а в write, соответственно, его снятие?

Да.


> Годятся ли для этого функции?
> http://php.net/manual/en/ref.sem.php

Вполне годятся.
 
Сверху