Превосходный статический файловый (html) кеш сайта php - PullRequest
6 голосов
/ 06 января 2012

У меня есть веб-сайт, который в основном отображает вещи без каких-либо форм и пост-запросов.Этот сайт основан на PHP и размещен на виртуальном хостинге.Это редко меняется.Я хотел бы включить кэширование для этого сайта.Это общий хостинг, поэтому мне нужно решение, которое:

  • не использует Memcached
  • , не нужно перемещать мой сайт на VPS
  • , не использовать APC или другие вещи

Итак, в основном я хотел бы выполнить кеширование каждого дочернего сайта в HTML и попросить PHP в течение 5 минут получить кешированную версию HTML текущего дочернего сайта и отобразить ее пользователю.И через 5 минут, чтобы обновить кеш.

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

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

Я думаю, она будет работать следующим образом:

<?

if (current_site_cache_is_valid())
{
   display_cached_version();
   die;
}

..mywebsite rendering code

?>

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

Ответы [ 5 ]

5 голосов
/ 06 января 2012

Так я обычно делаю, однако я не знаю ни вашего дизайна URL, ни вашего расположения каталогов / файлов.

Я делаю это с .htaccess и mod_rewrite & shy; Документы .

Веб-сервер проверяет, существует ли кэшированный файл HTML, и если да, он доставляется. Вы также можете проверить его возраст.

Если он слишком старый или не существует, ваш скрипт PHP запускается. В начале вашего скрипта вы запускаете выходной буфер & shy; Docs . В конце вашего сценария вы получаете выходной буфер, помещаете содержимое в файл кэша и затем выводите его.

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

Я бы даже пошел дальше и запустил задание cron, которое удаляет старые кеш-файлы вместо проверки времени внутри .htaccess. После этого вы можете сделать переписывание менее сложным, предпочитая файл .php.cached вместо файла .php.

3 голосов
/ 11 января 2012

У меня есть простой алгоритм для кэширования HTML, основанный на следующих условиях

  • Пользователь - гость (вошедшие в систему пользователи имеют набор файлов cookie blog_user)
  • URI запросаэто GET, который не содержит параметров запроса
  • Существует HTML-версия файла кэша

, затем запускается правило перезаписи .htaccess, отображающее запрос в кэшированный файл.Предполагается, что все остальное зависит от контекста и поэтому не может быть кэшировано.Обратите внимание, что я использую сопоставление URI в стиле Википедии для своего блога, поэтому /article-23 отображается на /index.php=article-23, когда не кэшируется.

Я использую один файл доступа HTML в моей директории DOCUMENT_ROOT, и вот соответствующая выдержка.Это третье правило переписывания, которое делает то, что вы хотите.Любой сценарий, который генерирует кэшируемый O / P, оборачивает это в пару ob_start() ob_get_clean() и записывает файл кэша HTML (хотя все это обрабатывается моим механизмом шаблонов).При необходимости обновления также очищают каталог кэша HTML.

RewriteEngine on
RewriteBase /

# ...
# Handle blog index
RewriteRule ^blog/$                                    blog/index               [skip=1]

# If the URI maps to a file that exists then stop.  This will kill endless loops

RewriteCond %{REQUEST_FILENAME}                        -f
RewriteRule ^blog/.*                                   -                        [last]

# If the request is HTML cacheable (a GET to a specific list, with no query params)
# the user is not logged on and the HTML cache file exists then use it instead of executing PHP

RewriteCond %{HTTP_COOKIE}                             !blog_user
RewriteCond %{REQUEST_METHOD}%{QUERY_STRING}           =GET                     [nocase]
RewriteCond %{DOCUMENT_ROOT}/blog/html_cache/$1.html   -f
RewriteRule ^blog/(article-\d+|index|sitemap.xml|search-\w+|rss-[0-9a-z]*)$ \
                                                       blog/html_cache/$1.html  [last]

# Anything else relating to the blog pass to index.php
RewriteRule blog/(.*)                                  blog/index.php?page=$1   [qsappend,last]

Надеюсь, это поможет.Мой блог описывает это более подробно.:-)

2 голосов
/ 14 августа 2012

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

Оригинал:

$cachefile = 'cache/index-cached.html';

Изменено:

$cachefile = $_SERVER['DOCUMENT_ROOT'].'/cache/'.pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_FILENAME).'-cached.html';

Для этого нужно взять имя файла любого файла, в котором он находится, за вычетом расширения (в моем случае - .php) и добавить «-cached».html "метка и новое расширение кешированного файла.Вероятно, есть более эффективные способы сделать это, но это работает для меня и, надеюсь, сэкономит другим время и усилия.

2 голосов
/ 09 мая 2012

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

Вы можете выполнять статическое кэширование в PHP без .htaccess или других хитростей.Я нашел это в http://simonwillison.net/2003/may/5/cachingwithphp/:

<?php
$cachefile = 'cache/index-cached.html';
$cachetime = 5 * 60;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
    include($cachefile);
    echo "<!-- Cached copy, generated ".date('H:i', filemtime($cachefile))." -->\n";
    exit;
}
ob_start(); // Start the output buffer

/* The code to dynamically generate the page goes here */

// Cache the output to a file
$fp = fopen($cachefile, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush(); // Send the output to the browser
?>
1 голос
/ 06 января 2012

Вы должны попробовать skycache . edit: этот проект тоже классный: cacheme

Другое решение заключается в использовании auto_prepend_file / auto_append_file. Примерно то, что описано в этом уроке: Кэширование вывода для начинающих

...