Отримання RSS

Основою буде мій улюблений інструмент – Zend Framework (використовуємо останню, trunk версію). Якщо ви знайомі з його можливостями, що відразу запропонуйте компонент Zend_Feed, який має вбудовані можливості для вилучення зі сторінки стрічок. Однак не поспішайте, на практиці завдання не таке й просте. Тому вирішуватимемо її поступово.

Нормалізація URL.

Отримання прямих лінків на стрічки.

  1. $cache = Zend_Cache::factory( 'Core' ,
  2. 'File',
  3. array(
  4. 'lifetime' => 24*3600,
  5. 'automatic_serialization' => true ,
  6. 'caching' => true ,
  7. 'cache_id_prefix' => 'preview_feed_',
  8. 'write_control' => true ,
  9. 'ignore_user_abort' => true
  10. ),
  11. array(
  12. 'read_control_type' => 'adler32',
  13. 'cache_dir' => '/tmp/cache'
  14. ));
  15. Zend_Feed_Reader::setCache($cache);
  16. Zend_Feed_Reader::useHttpConditionalGet( true );
* Цей source code був highlighted with Source Code Highlighter.

Наприклад, візьмемо навмання наступний список:

  1. $_url = array(
  2. 'http://www.cnbc.com/id/19789731/device/rss/rss.xml' ,
  3. 'http://www.planet-php.net/',
  4. 'ajaxian.com' ,
  5. 'http://twitter.com/abrdev',
  6. 'http://verens.com/archives/2009/12/28/multiple-file-uploads-using-html5/');
* Цей source code був highlighted with Source Code Highlighter.

Далі пропустимо його через валідатор, описаний вище і отримаємо повний масив URL.

  1. //масив лінків, які готові до обробки (валідні URI)
  2. $_links = Array();
  3. echo "Checking URL. " ;
  4. foreach ($_url as $u)
  5. echo "Original URL:" . $u . ". ";
  6. $_url = self::_val >if ($_url === false ) continue ;
  7. else
  8. $_links[] = $_url;
  9. >
* Цей source code був highlighted with Source Code Highlighter.

  1. foreach ($_links as $fl)
  2. //пробуємо вийняти URL із зазначеного сайту
  3. try
  4. $_lhttp = Zend_Uri_Http::fromString($fl);
  5. if ($_lhttp->val >//перевіримо та отримаємо ім'я сайту
  6. $site = $_lhttp->getHost();
  7. $_feeds_links[$site] = Array();
  8. >
  9. else
  10. // якщо не вийшло перевірити, пропускаємо
  11. continue;
  12. >
  13. catch (Zend_Uri_Exception $e)
* Цей source code був highlighted with Source Code Highlighter.

Зверніть увагу, якщо ми намагаємося завантажити фід безпосередньо, ми не знаємо, який формат буде, тому для перевірки результату використовуємо той факт, що всі класи фідів мають спільного предка, абстрактний клас Zend_Feed_Reader_FeedAbstract. Також у цьому випадку буде деяке дублювання, тому що далі ми отримуватимемо останні записи з фідів. Але оскільки ми використовуємо кешування, для випадку прямих посилань дані вже будуть у кеші, тому повторного запиту не буде.

Отримання останніх записів стрічки.

Якщо на цьому етапі ми зустрінемося з помилкою, то просто пропускаємо стрічку — у кращому разі, на сторінці буде ще одна стрічка, але іншого формату, у найгіршому — ми нічого не знайдемо. Коли стрічка імпортована, ми отримаємо заголовок, а далі в циклі 10 останніх записів, для кожного з яких отримаємо посилання, назву та дату створення (дата завжди йде до GMT). У тестовому прикладі я відразу формую рядок, в реальності швидше за все ви кожен з компонентів збережете окремо, а час, можливо, приведете до єдиногостандарту (наприклад, з урахуванням поточної локалі користувача) та конвертуєте в UNIX TIMESTAMP для зручності обробки.

Retriving last feed items. ';

  • $_feeds_items = Array(); //повідомлення у фіді
  • $_item_per_feed = 10; //Скільки повідомлень зі стрічки тягнути
  • foreach ($_feeds_links as $_flinks)
  • if (count($_flinks) > 0)
  • foreach ($_flinks as $fl)
  • try
  • $_x_feed = Zend_Feed_Reader::import($fl);
  • // може бути як Atom, і RSS,
  • //тому перевіряємо за абстрактним класом-предком
  • if ($_x_feed instanceOf Zend_Feed_Reader_FeedAbstract)
  • $tmpx = Array( 'title' => null , 'items' => Array());
  • $tmpx[ 'title' ] = htmlspecialchars($_x_feed->getTitle(), ENT_QUOTES);
  • $i = 0;
  • foreach ($_x_feed as $fitm)
  • if ($i //отримати назву, лінк і дату (у GMT)
  • //GUID - md5(getId());
  • $tmpx[ 'items' ][] = '.$fitm->getLink(). '" target="_blank">' .htmlspecialchars($fitm->getTitle(), ENT_QUOTES) ' at ' . $fitm->getDateCreated()->toString() .
  • >
  • else break;
  • >
  • $_feeds_items[$fl] = $tmpx;
  • >
  • >
  • catch (Zend_Exception $e)
  • >
  • >
  • >
  • // Подивимося результат?
  • var_dump($_feeds_items);
  • * Цей source code був highlighted with Source Code Highlighter.

    Результат ми поки що просто виводимо через var_dump в браузер (адже це лише тестовий скрипт). У реальній системі всі ці дані пакуються в JSON-масив і відправляються клієнту, який відображає користувачеві та дає можливість вибрати одну зі стрічок для передплати. Звичайно, можна було б зробити все за користувача - наприклад, вУ випадку кількох стрічок, які відрізняються лише форматом, перевіряти збіг ID новин, і якщо вони однакові, то просто брати кращий формат і все. Але це залежить від специфіки конкретних завдань.

    Хардкорна конфа за С++. Ми запрошуємо лише профі.