Главная страница статей --> Советы по фотошопу, графике и хитрости в построении php кода

Слежение за контентом на динамических сайтах

Источник: realcoding.net

[2 страница]
<?php

// Файл content_monitoring.inc.php, система контент-мониторинга.
// Должен лежать в той же папке, что и Ваши скрипты.

if (!isset($page_id)) $page_id = $_SERVER[PHP_SELF];
// $page_id это идентификатор страницы в базе данных.
// Если Вы используете схему 1 скрипт = 1 страница, оставьте все как есть.
// Если у Вас один скрипт генерирует много концептуально разных страниц,
// придется генерировать $page_id этими скриптами динамически.
// Переменная не должна содержать ничего кроме латиницы, цифр и подчеркивания.

ConnectToDatabase(); // Соединяемся с базой данных.
// Функция ConnectToDatabase() не определена в этом файле, так как
// подключение к БД MySQL и обработка возникших ошибок выходит
// за рамки этой статьи. Вам придется самому написать эту функцию.

$page_all_contents = ob_get_contents(); // Достаем вывод скрипта из буфера
$page_main_content = preg_replace(#.*?(<!--content-->(.*?)<!--/content-->$)#is, $2, $page_all_contents);
$page_hash = md5($page_main_content); // Вычисляем хэш нужной части страницы

// Проверим, создана ли таблица статистики...
if (!mysql_num_rows(mysql_query(SHOW TABLES LIKE content_monitoring))) {
   
// Таблица статистики не найдена.
   
mysql_query(CREATE TABLE content_monitoring (cm_id VARCHAR(255) NOT NULL, cm_md5 CHAR(32), cm_modified TIMESTAMP(14), PRIMARY KEY(cm_id(255)))); // Создаем таблицу.
   
mysql_query(INSERT INTO content_monitoring VALUES ($page_id, $page_hash, NULL)); // Пишем в таблицу первую запись.
}

// Достаем из базы данных информацию о текущей странице.
$FILE_INFO = mysql_fetch_row(mysql_query(SELECT cm_id, cm_md5, UNIX_TIMESTAMP(cm_modified) as modified FROM content_monitoring WHERE cm_id = $page_id));

if (empty(
$FILE_INFO)) {
   
// Запись для файла не найдена.
   
mysql_query(INSERT INTO content_monitoring VALUES ($page_id, $page_hash, NULL);); // Создаем запись о текущем файле.
   
$FILE_INFO[2] = time(); // Модификация - сейчас.
   
$last_modified = gmdate(D, d M Y H:i:s, $FILE_INFO[2]);
}
else {
   
// Запись для файла найдена.
   
if ($page_hash != $FILE_INFO[1]) {
   
mysql_query(UPDATE content_monitoring SET cm_md5=$page_hash WHERE cm_id=$page_id;); // Обновляем запись о текущем файле, если он изменился.
   
$FILE_INFO[2] = time(); // Модификация - сейчас.
   
}

   
$last_modified = gmdate(D, d M Y H:i:s, $FILE_INFO[2]);

   
// Дальше делаем обработку Conditional GETа:
   
if (!isset($_SERVER[HTTP_IF_NONE_MATCH]) && !isset($_SERVER[HTTP_IF_MODIFIED_SINCE])) {
   
// Conditional Get не задан - просто отдаем файл.
   
header(ETag: .$page_hash. ); // присваеваем метку
   
header(Last-Modified: $last_modified GMT);  // последнее изменение - сейчас
   
header(Expires: .gmdate(D, d M Y H:i:s, time()+60*10). GMT); // страница остается неизменной 10 минут
   
}

    elseif (!isset(
$_SERVER[HTTP_IF_NONE_MATCH]) && isset($_SERVER[HTTP_IF_MODIFIED_SINCE])) {
   
// Случай первый - Conditional GET задан, проверка только по If-Modified-Since:
   
$unix_ims = strtotime($_SERVER[HTTP_IF_MODIFIED_SINCE]); // значение If-Modified-Since в UNIX формате
   
if ($unix_ims > time() !is_int($unix_ims)) {
       
// Ошибка Conditional GET - просто отдаем файл.
       
header(ETag: .$page_hash. ); // присваеваем метку
       
header(Last-Modified: $last_modified GMT);  // последнее изменение - сейчас
       
header(Expires: .gmdate(D, d M Y H:i:s, time()+60*10). GMT); // страница остается неизменной 10 минут
   
}
    else {
       
// Conditional GET корректен.
       
if ($unix_ims >= $FILE_INFO[2]) {
            
// Копия файла в кеше клиента не устарела - сообщаем ему об этом...
            
header(HTTP/1.1 304 Not Modified); // не модифицировано
            
header(ETag: .$page_hash. ); // присваеваем метку
            // ...и заканчиваем выполнение скрипта, не отсылая сам файл.
            
while(ob_get_level()) ob_end_clean();
            exit;
        }
        else {
            
// Похоже, что копия клиента устарела.
            
header(ETag: .$page_hash. ); // присваеваем метку
            
header(Last-Modified: $last_modified GMT);  // последнее изменение - сейчас
            
header(Expires: .gmdate(D, d M Y H:i:s, time()+60*10). GMT); // страница остается неизменной 10 минут
            
}
        }
    }

    elseif (isset(
$_SERVER[HTTP_IF_NONE_MATCH]) && !isset($_SERVER[HTTP_IF_MODIFIED_SINCE])) {
   
// Случай второй - Conditional GET задан, проверка только по If-None-Match:
   
$INM = split([,][ ]?, $_SERVER[HTTP_IF_NONE_MATCH]); // массив значений If-None-Match
   
foreach($INM as $enity) {
        if (
$enity == \$page_hash\) {
            
// Копия файла в кеше клиента не устарела - сообщаем ему об этом...
            
header(HTTP/1.1 304 Not Modified); // не модифицировано
            
header(ETag: .$page_hash. ); // присваеваем метку
            // ...и заканчиваем выполнение скрипта, не отсылая сам файл.
            
while(ob_get_level()) ob_end_clean();
            exit;
            }
       
// Если дошло до этой линии, копия клиента устарела. Отдаем файл.
       
header(ETag: .$page_hash. ); // присваеваем метку
       
header(Last-Modified: $last_modified GMT);  // последнее изменение - сейчас
       
header(Expires: .gmdate(D, d M Y H:i:s, time()+60*10). GMT); // страница остается неизменной 10 минут
       
}
    }

    else {
   
// Случай третий - проверка и по If-Modified-Since, и по If-None-Match:
   
$unix_ims = strtotime($_SERVER[HTTP_IF_MODIFIED_SINCE]); // значение If-Modified-Since в UNIX формате
   
$INM = split([,][ ]?, $_SERVER[HTTP_IF_NONE_MATCH]); // массив значений If-None-Match
   
if ($unix_ims > time() !is_int($unix_ims)) {
       
// Ошибка Conditional Get - просто отдаем файл.
       
header(ETag: .$page_hash. ); // присваеваем метку
       
header(Last-Modified: $last_modified GMT);  // последнее изменение - сейчас
       
header(Expires: .gmdate(D, d M Y H:i:s, time()+60*10). GMT); // страница остается неизменной 10 минут
       
}
    else {
       
// Conditional GET корректен.
       
foreach($INM as $enity) {
            if (
$enity == \$page_hash\ && $unix_ims >= $FILE_INFO[2]) {
            
// Копия файла в кеше клиента не устарела - сообщаем ему об этом...
            
header(HTTP/1.1 304 Not Modified); // не модифицировано
            
header(ETag: .$page_hash. ); // присваеваем метку
            // ...и заканчиваем выполнение скрипта, не отсылая сам файл.
            
while(ob_get_level()) ob_end_clean();
            exit;
            }
       
// Если дошло до этой линии, копия клиента устарела. Отдаем файл.
       
header(ETag: .$page_hash. ); // присваеваем метку
       
header(Last-Modified: $last_modified GMT);  // последнее изменение - сейчас
       
header(Expires: .gmdate(D, d M Y H:i:s, time()+60*10). GMT); // страница остается неизменной 10 минут
       
}
    }
}
}

?>

Несколько слов напоследок


Данная статья, мнение ее автора по отношению к поднятой проблеме, а также предложенные методы решения этой проблемы не претендуют на универсальность — вполне возможно (а, скорее всего, так и есть), что существует более простое и лучшее решение для Вашего случая. Автор не ставил перед собой цель создать нечто гениальное, что будет способно существенно изменить Интернет — это невозможно. Он лишь хотел показать один из возможных путей небольшого облегчения жизни веб-разработчикам, большей частью начинающим.

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

В любом случае буду рад, если кому-нибудь помог.

Контакты
Редакция:
[0.001]