fetch_feed()
Получает внешний фид и разбирает его на данные (парсит его).
Функция нужна, чтобы получить RSS фид в виде SimplePie объекта и закэшировать результат.
Для получения и парсинга фида fetch_feed() использует популярный класс SimplePie. Фид кэшируется и кэш в последствии обновляется каждые 12 часов.
Данные кэшируются в базу данных во временные опции.
Если установлен плагин постоянного объектного кэширования, то функция будет кэшировать не в БД, а в хранилище для объектного кэша.
Есть очень похожая функция fetch_rss( $url )
Подробнее о методах класса SimplePie читайте в документации (англ.).
Хуки из функции
Возвращает
SimplePie\SimplePie|WP_Error
.
Использование
fetch_feed( $url );
- $url(строка) (обязательный)
- Ссылка (УРЛ) на фид который нужно получить. В результате по этой ссылке будет получен создан объект (массив) SimplePie.
Примеры
#1 Получим 5 записей из фида у внешнего сайта
Пример, который получает и выводит на экран ссылки на существующий RSS фид. В примере мы ограничиваем вывод только 5-ю последними записями в фиде.
<h2>Поcледние новости с блога blog.ru</h2> <?php // делаем функцию fetch_feed() доступной, обычно эта строка не нужна include_once ABSPATH . WPINC . '/feed.php'; // Получаем фид и создаем из него SimplePie объект. $rss = fetch_feed( 'http://blog.ru/feed' ); // Проверяем, что объект успешно создан if ( ! is_wp_error( $rss ) ) { // Указываем что максимум мы хотим выводить 5 записей фида $maxitems = $rss->get_item_quantity( 5 ); // Создаем массив всех записей фида, начиная с первой записи (0 - начало) $rss_items = $rss->get_items( 0, $maxitems ); } ?> <ul> <?php if( $maxitems == 0 ){ echo '<li>Нет записей.</li>'; } else { // Пробегаемся по массиву и выводим ссылку на каждую запись foreach( $rss_items as $item ){ ?> <li> <a href="<?= esc_url( $item->get_permalink() ) ?>" title="<?= esc_attr( 'Posted ' . $item->get_date( 'j F Y | g:i a' ) ) ?>" > <?= esc_html( $item->get_title() ) ?> </a> </li> <?php } } ?> </ul>
#2 Еще пример: получим 5 записей фида стороннего сайта
Прочитаем фид http://mysite.com/feed/ и получим из него первые 5 записей.
include_once ABSPATH . WPINC . '/feed.php'; $rss = fetch_feed( 'http://mysite.com/feed/' ); $rss_items = $rss->get_items( 0, $rss->get_item_quantity(5) ); if ( ! $rss_items ) { echo 'no items'; } else { foreach ( $rss_items as $item ) { echo '<p><a href="' . $item->get_permalink() . '">' . $item->get_title() . '</a></p>'; } }
#3 Управление временем жизни кэша фидов
Результат получения фида кэшируется на 12 часов. Чтобы изменить время кэша для функции fetch_feed(), нужно использовать хук wp_feed_cache_transient_lifetime.
add_filter( 'wp_feed_cache_transient_lifetime', 'speed_up_feed', 10, 2 ); function speed_up_feed( $interval, $url ) { if( 'http://myexample.com/feed/' === $url ){ return 3600; // 1 час } return $interval; }
#4 Отключение кэширования на время разработки
По ходу манипуляций с фидом, необходимо отключить кэширования, а то оно будет сильно мешать. Сделать это можно через хук wp_feed_options
// отключаем кэширование фидов. Только если включен режим разработки WP_DEBUG if( defined('WP_DEBUG') && WP_DEBUG ){ add_action( 'wp_feed_options', function( &$feed ){ $feed->enable_cache(false); } ); }
ВАЖНО! Обязательно отключите этот код на рабочем сайте. Потому что он может увеличить скорость загрузки страниц сайта в разы!
Кэширование фидов не работает с включенной константой WP_DEBUG
Имейте ввиду, что если включена константа WP_DEBUG, то фид не кэшируется. Срабатывает такой код ядра:
function do_not_cache_feeds(&$feed) { $feed->enable_cache(false); } if ( defined('WP_DEBUG') && WP_DEBUG ) { add_action( 'wp_feed_options', 'do_not_cache_feeds' ); }
Кэширование в браузере
Также обратите внимание, что кэширование может происходить в браузере, чтобы его обойти обновляйте страницу через ctrl + F5. Или можно добавить такой хук:
// отключим кэширование в барузере для запросов фидов add_filter( 'wp_headers', function( $headers ){ if( !empty( $GLOBALS['wp']->query_vars['feed'] ) ){ unset( $headers['ETag'], $headers['Last-Modified'] ); } return $headers; } );
#5 Очистка кэша всех фидов в WordPress
Для запуска кода, нужно добавить в URL параметр ?clear_feeds_cache.
// Очистка кэша всех фидов в WordPress if( isset( $_GET['clear_feeds_cache'] ) ){ global $wpdb; $cleared = $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '\_transient%\_feed\_%'" ); die( var_dump( $cleared ) ); }
Заметка: если на сайте включено объектное кэширование, то этот код не сработает.
#6 Как распарсить фид из локального файла
Вообще библиотека SimplePie позволяет передать локальный файл с данными фида, чтобы распарсить этот фид. Но WordPress почему-то отключил эту возможность, переписав конструктор класса SimplePie_File, расширив этот класс своим классом WP_SimplePie_File.
И поэтому, если в fetch_feed() указать путь до локального файла, ничего работать не будет.
Исправить это можно с помощью хука wp_feed_options:
$feed_path = PROJECT_ROOT_DIR . '/_tmp/feed.xml'; add_action( 'wp_feed_options', 'change_simple_pie_options', 10, 2 ); function change_simple_pie_options( $simplepie, $url ){ /** * INFO: We need to create the TEMP_SimplePie_File class to fetch the feed * from a local file (not HTTP). To do that, we need to use the native {@see SimplePie_File} class, * but it is overridden by WP with the {@see WP_SimplePie_File} class, and we cannot change it * by simply passing the {@see SimplePie_File} class to the {@see SimplePie::set_file_class()} method, * because the {@see SimplePie_Registry::register()} method has an `is_subclass_of()` * check, and this check does not pass like: is_subclass_of('SimplePie_File', 'SimplePie_File'). */ class TEMP_SimplePie_File extends SimplePie_File {} $simplepie->set_file_class( TEMP_SimplePie_File::class ); $simplepie->set_cache_duration( 0 ); } $simplepie = fetch_feed( $feed_path ); $items = $simplepie->get_items( 0, 10 ); foreach( $items as $item ){ echo $item->get_title() ."\n"; }
Зачем это может быть нужно? Например:
- У вас есть отдельный сервис, который собирает фиды и кладет их в файлы, которые затем нужно распарсить через WP.
- Вам нужно парсить фид, но этот фид заблокирован (защищен) так, что через PHP получить его невозможно (проверяется поддержка куки — на Cloudflare есть подобная защита, обойти которую стандартным curl-запросом невозможно). В этом случае можно скачивать такой фид через какой-нибудь безголовый браузер и класть в файл, а затем парсить фид из файла.
Список изменений
С версии 2.8.0 | Введена. |