Правильная организация RSS
В пользе RSS уже давно никто не сомневается. Я позволю себе сказать пару слов о том, как правильно сделать
Фактически формат RSS представляет
собой
<?xml version="1.0" encoding="windows-1251"?>
<rss version="2.0">
<channel>
<title>Название RSS-потока</title>
<link>http://site.ru</link>
<description>Описание RSS-потока</description>
<item>
<title>Название 1</title>
<link>http://site.ru/articles/1</link>
<description>Описание статьи 1</description>
<author>Автор <author@site.ru></author>
<pubDate>Sun, 25 Mar 2007 00:00:00 +0300</pubDate>
</item>
<item>
<title>Название 2</title>
<link>http://site.ru/articles/2</link>
<description>Описание статьи 2</description>
<author>Автор <author@site.ru></author>
<pubDate>Sun, 18 Mar 2007 00:00:00 +0300</pubDate>
</item>
<item>
<title>Название 3</title>
<link>http://site.ru/articles/3</link>
<description>Описание статьи 3</description>
<author>Автор <author@site.ru></author>
<pubDate>Sun, 11 Mar 2007 00:00:00 +0300</pubDate>
</item>
</channel>
</rss>
Для подобных целей подойдет текстовый редактор, или простейший скрипт (недостатки такого подхода очевидны, впрочем, я о них уже писал).
Понятно, что если на сайте есть хотя бы минимальная автоматизация, RSS может генерироваться скриптом, например, на PHP. Можно предложить два разумных способа работы этого скрипта:
- Скрипт вызывается при обновлении сайта и результаты своей работы сохраняет в обычный
XML-файл, на который вы будете давать ссылки. - Скрипт отрабатывает каждый раз, когда браузер (или иной пользовательский агент) обращается к RSS и отдает результаты браузеру.
Здесь нужно остановиться и обратить внимание на основные факты: зачем вы делаете RSS, большая ли аудитория у сайта и т. д. Различия между первым и вторым способом в основном связаны с особенностями работы протокола HTTP, а именно, с заголовками Last-Modified и If-Modified-Since (ознакомьтесь с описанием работы этих заголовков, повторяться смысла нет, а дальше они активно используются). Различия между этими двумя способами мы посмотрим на примере первого и повторных обращений к
Статический XML-файл
При первом обращении содержимое этого файла отдается целиком. При повторных обращениях (когда
Динамический скрипт
При первом обращении он отдает информацию обо всех элементах. При повторных обращениях скрипт сообщает, что изменений не было, и ничего не отправляет. Однако если мы добавили, например, еще одну статью, то по содержимому заголовка If-Modified-Since скрипт определяет, когда было последнее обращение к RSS, и выдает только добавившиеся элементы (идея найдена на xpoint.ru). Именно здесь заключается то улучшение, которого можно добиться вторым способом.
Можно найти еще одно преимущество: если мы
Описание скрипта
Есть смысл через RSS отправлять
информацию о нескольких последних статьях (обычно так и делают). Чем чаще в RSS появляются новые элементы, тем больше информации нужно
экспортировать при постоянной частоте обращения, чтобы подписанные пользователи
не пропустили
В скрипте предполагается, что функция get_recent() возвращает массив с описанием статей, причем количество элементов будет задаваться размером массива. Её придется писать вам самим. Это просто, нужно всего лишь при переиндексации (если сайт использует файлы) записать в определенный файл информацию о последних статьях, и считывать ее в вышеупомянутой функции. Или обращаться к базе данных и выбирать информацию о последних статьях.
Функция get_last_modified() должна возвращать дату и время последней новости, экспортируемой через RSS, и это значение будет установлено в заголовке Last-Modified. Хотя здесь можно отдавать время внесения последних изменений в новости, экспортируемые через RSS в надежде на то, что программы для чтения RSS обновят ранее полученную информацию.
Следует отметить, что в некоторых полях отдаваемого XML, например, в поле description
могут присутствовать
Итак, сам скрипт:
<?
// Запрет кеширования, см. описание
function no_cache() {
header("Expires: Mon, 26 Jul 1997 00:00:00 GMT");
header("Pragma: no-cache");
}
// Перевод даты из формата RFC 2822 в unixstamp
function date2unixstamp($s) {
$months = array (
"Jan"=>1, "Feb"=>2, "Mar"=>3,
"Apr"=>4, "May"=>5, "Jun"=>6,
"Jul"=>7, "Aug"=>8, "Sep"=>9,
"Oct"=>10, "Nov"=>11, "Dec"=>12);
$a = explode(" ", $s);
$b = explode(":", $a[4]);
return gmmktime($b[0], $b[1], $b[2],
$months[$a[2]], $a[1], $a[3]);
}
// Получение массива элементов
function get_recent() {
...
}
// Дата и время последнего изменения
function get_last_modified() {
...
}
$HTTP_HOST = isset($_SERVER["HTTP_HOST"]) ?
$_SERVER["HTTP_HOST"] : "site.ru"; // ваш сайт
no_cache();
$recent_articles = get_recent();
// Буферизация для установки заголовка Content-Length
// и сжатия отправляемых данных
ob_start();
ob_start("ob_gzhandler");
echo '<?xml version="1.0" encoding="windows-1251"?>'."\n";
?><rss version="2.0">
<channel>
<title>Название RSS</title>
<link><?=$HTTP_HOST?></link>
<description>Описание</description>
<?
$last_date = 0;
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
$last_date = date2unixstamp($_SERVER["HTTP_IF_MODIFIED_SINCE"]);
}
$counter = 0;
foreach($recent_articles as $recent) {
if ($recent["date"] > $last_date) {
$counter++;
?>
<item>
<title>
<?=htmlspecialchars($recent["title"])?>
</title>
<link><?=$recent["link"]?></link>
<description>
<?=htmlspecialchars($recent["desc"])?>
</description>
<author>Автор <author@site.ru></author>
<guid><?=$recent["link"]?></guid>
<pubDate><?=date("r", $recent["date"])?></pubDate>
</item>
<?
}
}
?>
</channel>
</rss>
<?
if (!$counter) {
header("HTTP/1.1 304 Not Modified");
exit();
}
ob_end_flush();
header("Content-Length: ".ob_get_length());
header("Last-Modified: ".
gmdate("D, d M Y H:i:s", get_last_modified())." GMT");
header("Content-Type: text/xml; charset=WINDOWS-1251");
ob_end_flush();
?>
Чтобы скрипт заработал, достаточно на него дать ссылку. Если вы хотите, чтобы у него было «красивое» имя вроде http://site.ru/rss.xml, пропишите в файл .htaccess следующее:
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^rss.xml$ some_path/php123/rss.php [L]
some_path/php123/rss.php — это «некрасивый» путь, по которому лежит наш скрипт. Если mod_rewrite не установлен, тогда пропишите туда же вот что:
AddType application/x-httpd-php xml
и поместите скрипт прямо в файл rss.xml. Будьте внимательны! В последнем случае все файлы с расширением xml будут обрабатываться парсером PHP.
Чтобы браузеры смогли определить, что на вашем сайте есть RSS, в разделе описаний страницы следует разместить тег <link>:
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=windows-1251" />
<title>Заголовок страницы</title>
<link rel="alternate" type="application/rss+xml"
title="Название RSS" href="http://site.ru/rss.xml" />
</head>
<body>
...
</body>
</html>
На этом всё. Пользуйтесь на здоровье.
Комментарии
Ещё бы про этот mod_rewrite написали, как вы его понимаете. Я вот регулярки перловские в php замастерил, а вот этот mod_rewrite сильно сложен.
Если выкинуть ob_start(), то данные перед отправкой браузеру не будут сжиматься, и еще возникнут трудности с установкой заголовка
get_last_modified() должна возвращать дату последнего изменения информации, отсылаемой через RSS (например, дату последней новости). Вы правы, я про нее не написал. Исправлю.
"Не удается отобразить страницу XML
Не удается просмотреть ввод XML с использованием списка стилей . Исправьте ошибку и затем нажмите кнопку «Обновить»или повторите попытку позднее. "
Насколько я понял, ваш RSS не открывается в браузере (каком, кстати?). Попробуйте проверить его, например, на feedvalidator.org. Если RSS доступен из Интернета, дайте ссылку на него, я посмотрю, что там не в порядке.
<link>
Любой парсер xml ругается на знак &, который в моем случае необходим для передачи доп. параметров. Как можно это разрулить именно в xml (rss), если учесть, что параметры передавать необходимо обязательно?
Я помещу у себя со ссылкой на Ваш сайт.
Оставьте свой комментарий