fetch_feed()
Build SimplePie object based on RSS or Atom feed from URL.
Hooks from the function
Return
SimplePie\SimplePie|WP_Error
. SimplePie object on success or WP_Error object on failure.
Usage
fetch_feed( $url );
- $url(string|string[]) (required)
- URL of feed to retrieve. If an array of URLs, the feeds are merged using SimplePie's multifeed feature. See also http://simplepie.org/wiki/faq/typical_multifeed_gotchas
Examples
#1 Get the last 5 posts of the feed from the external site
An example that gets and displays links to an existing RSS feed. In the example we limit the output to the last 5 posts in the feed.
<h2>Latest news from blog.ru</h2> <?php // make fetch_feed() available, usually this (string) is not needed include_once ABSPATH . WPINC . '/feed.php'; // Get a feed and create a SimplePie object from it. $rss = fetch_feed( 'http://blog.ru/feed' ); // Check that the object was successfully created if ( ! is_wp_error( $rss ) ) { // Specify that we want to output a maximum of 5 feed posts $maxitems = $rss->get_item_quantity( 5 ); // create an array of all feed posts, starting from the first post (0 is the beginning) $rss_items = $rss->get_items( 0, $maxitems ); } ?> <ul> <?php if ( $maxitems == 0 ) { echo '<li>No posts.</li>'; } // Run through the array and display a link to each post 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>
#2 Get 5 feed posts from a third-party site
Let's read the feed http://mysite.com/feed/ and get the first 5 posts from it.
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 Managing the lifetime of the feed cache
The result of fetching a feed is cached for 12 hours. To change cache time for this function, you can use hook 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 hour } return $interval; }
#4 Disabling caching during development
In the process of manipulating the feed, it is necessary to disable the caching, otherwise it will interfere a lot. This can be done through the hook wp_feed_options.
// disable feeds caching. Only if WP_DEBUG development mode is enabled if( defined('WP_DEBUG') && WP_DEBUG ){ add_action( 'wp_feed_options', function( &$feed ){ $feed->enable_cache(false); } ); }
IMPORTANT: Be sure to disable this code on the working site. Because it can increase the speed of loading pages of the site at times!
Feed caching does not work with constant WP_DEBUG enabled
Keep in mind that if constant WP_DEBUG is enabled, the feed is not cached. This is the kernel code that works:
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' ); }
Browser caching
Also note that the caching can occur in the browser, to bypass it, refresh the page via ctrl + F5. Or you can add such a hook:
// disable caching in the baruser for feed queries add_filter( 'wp_headers', function( $headers ){ if( !empty( $GLOBALS['wp']->query_vars['feed'] ) ){ unset( $headers['ETag'], $headers['Last-Modified'] ); } return $headers; } );
#5 Cleaning the cache of all feeds in WordPress
To run the code, add the parameter ?clear_feeds_cache to the URL.
// Cleaning the cache of all feeds in 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 ) ); }
Note: if object caching is enabled on the site, this code will not work.
#6 How to parse a feed from a local file
In general, the SimplePie library allows you to pass a local file with feed data to parse this feed. However, WordPress has somehow disabled this feature by rewriting the constructor of the SimplePie_File class, extending this class with its own class WP_SimplePie_File.
Therefore, if you specify the path to a local file in fetch_feed(), nothing will work.
This can be fixed using the wp_feed_options hook:
$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"; }
Why might this be necessary? For example:
- You have a separate service that collects feeds and saves them to files, which then need to be parsed through WP.
- You need to parse a feed, but this feed is blocked (protected) in such a way that it cannot be obtained through PHP (cookie support is checked — there is similar protection on Cloudflare that cannot be bypassed with a standard curl request). In this case, you can download such a feed using some headless browser and save it to a file, and then parse the feed from the file.
Changelog
Since 2.8.0 | Introduced. |