Как кешировать динамическую страницу PHP - PullRequest
20 голосов
/ 24 сентября 2010

Как кэшировать PHP-страницу с запросом mysql. Любой пример будет отличным и полезным.

Ответы [ 5 ]

18 голосов
/ 29 апреля 2013

Я использую phpFastCache (для общего хостинга, если вы не хотите трогать php.ini и root для установки memcached). Проверьте Пример меню. Они имеют полный пример детализации и очень просты.

Сначала вы устанавливаете с помощью phpFastCache :: set, а затем получаете с помощью phpFastCache :: get - DONE!

Пример: сокращение вызовов базы данных

Ваш веб-сайт имеет 10 000 посетителей, которые находятся в сети, и ваша динамическая страница должна отправлять 10 000 одинаковых запросов в базу данных при каждой загрузке страницы. С phpFastCache ваша страница отправляет только 1 запрос в БД и использует кеш для обслуживания 9999 других посетителей.

<?php
    // In your config file
    include("php_fast_cache.php");
    phpFastCache::$storage = "auto";
    // you can set it to files, apc, memcache, memcached, pdo, or wincache
    // I like auto

    // In your Class, Functions, PHP Pages
    // try to get from Cache first.
    $products = phpFastCache::get("products_page");

    if($products == null) {
        $products = YOUR DB QUERIES || GET_PRODUCTS_FUNCTION;
        // set products in to cache in 600 seconds = 5 minutes
        phpFastCache::set("products_page",$products,600);
    }

   OUTPUT or RETURN your $products
?>
13 голосов
/ 24 сентября 2010

Я предпочитаю использовать обратный прокси-сервер для кэширования, например Varnish .

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

<?php

function cache_file() {
    // something to (hopefully) uniquely identify the resource
    $cache_key = md5($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']);
    $cache_dir = '/tmp/phpcache';

    return $cache_dir . '/' . $cache_key;
}

// if we have a cache file, deliver it
if( is_file( $cache_file = cache_file() ) ) {
    readfile( $cache_file );
    exit;
}

// cache via output buffering, with callback
ob_start( 'cache_output' );

//
// expensive processing happens here, along with page output.
//

function cache_output( $content ) {
    file_put_contents( cache_file(), $content );
    return $content;
}

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

2 голосов
/ 19 августа 2015
    <?php
    //settings
    $cache_ext  = '.html'; //file extension
    $cache_time     = 3600;  //Cache file expires afere these seconds (1 hour = 3600 sec)
    $cache_folder   = 'cache/'; //folder to store Cache files
    $ignore_pages   = array('', '');

    $dynamic_url    = 'http://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']; // requested dynamic page (full url)
    $cache_file     = $cache_folder.md5($dynamic_url).$cache_ext; // construct a cache file
    $ignore = (in_array($dynamic_url,$ignore_pages))?true:false; //check if url is in ignore list

    if (!$ignore && file_exists($cache_file) && time() - $cache_time < filemtime($cache_file)) { //check Cache exist and it's not expired.
        ob_start('ob_gzhandler'); //Turn on output buffering, "ob_gzhandler" for the compressed page with gzip.
        readfile($cache_file); //read Cache file
        echo '<!-- cached page - '.date('l jS \of F Y h:i:s A', filemtime($cache_file)).', Page : '.$dynamic_url.' -->';
        ob_end_flush(); //Flush and turn off output buffering
        exit(); //no need to proceed further, exit the flow.
    }
    //Turn on output buffering with gzip compression.
    ob_start('ob_gzhandler');
    ######## Your Website Content Starts Below #########
    ?>
    <!DOCTYPE html>
    <html>
        <head>
            <title>Page to Cache</title>
        </head>
            <body>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ut tellus libero.
            </body>
    </html>
    <?php
    ######## Your Website Content Ends here #########

    if (!is_dir($cache_folder)) { //create a new folder if we need to
        mkdir($cache_folder);
    }
    if(!$ignore){
        $fp = fopen($cache_file, 'w');  //open file for writing
        fwrite($fp, ob_get_contents()); //write contents of the output buffer in Cache file
        fclose($fp); //Close file pointer
    }
    ob_end_flush(); //Flush and turn off output buffering

    ?>
2 голосов
/ 24 сентября 2010

запомните ваш html, а затем сделайте что-то вроде этого:

$memcache = memcache_connect('localhost', 11211);

$page  = $memcache->get('homepage');
if($page == ""){
    $mtime = microtime();
    $page = get_home();
    $mtime = explode(" ",$mtime);
    $mtime = $mtime[1] + $mtime[0];
    $endtime = $mtime;
    $totaltime = ($endtime - $starttime);
    memcache_set($memcache, 'homepage', $page, 0, 30);
    $page .= "\n<!-- Duly stored ($totaltime) -->";
}
else{
    $mtime = microtime();
    $mtime = explode(" ",$mtime);
    $mtime = $mtime[1] + $mtime[0];
    $endtime = $mtime;
    $totaltime = ($endtime - $starttime);
    $page .= "\n&lt;!-- served from memcache ($totaltime) -->";
}
die($page);
1 голос
/ 03 ноября 2017

Важной вещью, которую часто упускают из виду при обсуждении кэширования, является синхронизация процессов, чтобы избежать гонки потоков (см .: https://en.wikipedia.org/wiki/Race_condition).

Типичный сценарий кэширования в PHP без синхронизации выглядит следующим образом: если вы неесли ресурс не находится в кэше, или ресурс истек, его необходимо создать и поместить в кэш. Первый поток / процесс, который сталкивается с таким условием, пытается создать ресурс, и в течение этого времени другие потоки также будут создавать ресурс,что приводит к гонке потоков, сбою кэша и снижению производительности.

Проблема усугубляется количеством одновременных потоков и рабочей нагрузкой, созданной задачей создания ресурса. В загруженных системах это может привести к серьезным проблемам.

Существует очень мало систем кэширования для PHP, которые учитывают синхронизацию.

Одной из них является php-no-slam-cache: https://github.com/tztztztz/php-no-slam-cache

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...