WordPress как на ладони

fetch_feed()WP 2.8.0

Получает внешний фид и разбирает его на данные (парсит его).

Функция нужна, чтобы получить RSS фид в виде SimplePie объекта и закэшировать результат.

Для получения и парсинга фида fetch_feed() использует популярный класс SimplePie. Фид кэшируется и кэш в последствии обновляется каждые 12 часов.

Данные кэшируются в базу данных во временные опции. Если установлен плагин постоянного объектного кэширования, то функция будет кэшировать не в БД, а в хранилище для объектного кэша.

Есть очень похожая функция fetch_rss( $url )

Подробнее о методах класса SimplePie читайте в документации (англ.).

Возвращает

SimplePie|WP_Error. SimplePie объект данных о фиде или объект WP_Error в случае ошибки.

Использование

$feed = fetch_feed( $uri );
$uri(строка) (обязательный)
Ссылка (УРЛ) на фид который нужно получить. В результате по этой ссылке будет получен создан объект (массив) SimplePie.

Примеры

0

#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='<?php echo esc_url( $item->get_permalink() ); ?>'
				   title='<?php echo 'Posted ' . $item->get_date( 'j F Y | g:i a' ); ?>'
				>
					<?php echo esc_html( $item->get_title() ); ?>
				</a>
			</li>
		<?php }
	} ?>
</ul>
0

#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>';
	}
}
0

#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;
}
0

#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;
} );
0

#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 ) );
}

Заметка: если на сайте включено объектное кэширование, то этот код не сработает.

Список изменений

С версии 2.8.0 Введена.

Код fetch_feed() WP 6.5.2

function fetch_feed( $url ) {
	if ( ! class_exists( 'SimplePie', false ) ) {
		require_once ABSPATH . WPINC . '/class-simplepie.php';
	}

	require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php';
	require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php';
	require_once ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php';

	$feed = new SimplePie();

	$feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' );
	/*
	 * We must manually overwrite $feed->sanitize because SimplePie's constructor
	 * sets it before we have a chance to set the sanitization class.
	 */
	$feed->sanitize = new WP_SimplePie_Sanitize_KSES();

	// Register the cache handler using the recommended method for SimplePie 1.3 or later.
	if ( method_exists( 'SimplePie_Cache', 'register' ) ) {
		SimplePie_Cache::register( 'wp_transient', 'WP_Feed_Cache_Transient' );
		$feed->set_cache_location( 'wp_transient' );
	} else {
		// Back-compat for SimplePie 1.2.x.
		require_once ABSPATH . WPINC . '/class-wp-feed-cache.php';
		$feed->set_cache_class( 'WP_Feed_Cache' );
	}

	$feed->set_file_class( 'WP_SimplePie_File' );

	$feed->set_feed_url( $url );
	/** This filter is documented in wp-includes/class-wp-feed-cache-transient.php */
	$feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) );

	/**
	 * Fires just before processing the SimplePie feed object.
	 *
	 * @since 3.0.0
	 *
	 * @param SimplePie       $feed SimplePie feed object (passed by reference).
	 * @param string|string[] $url  URL of feed or array of URLs of feeds to retrieve.
	 */
	do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );

	$feed->init();
	$feed->set_output_encoding( get_option( 'blog_charset' ) );

	if ( $feed->error() ) {
		return new WP_Error( 'simplepie-error', $feed->error() );
	}

	return $feed;
}
1 комментарий
    Войти