PHPackages                             debril/feed-io - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. debril/feed-io

Abandoned → [php-feed-io/feed-io](/?search=php-feed-io%2Ffeed-io)ArchivedLibrary[CLI &amp; Console](/categories/cli)

debril/feed-io
==============

PHP library built to consume and serve JSONFeed / RSS / Atom feeds

v6.0.3(2y ago)2631.9M—3.5%63[8 PRs](https://github.com/alexdebril/feed-io/pulls)7MITPHPPHP &gt;=8.1CI passing

Since Jun 2Pushed 10mo ago13 watchersCompare

[ Source](https://github.com/alexdebril/feed-io)[ Packagist](https://packagist.org/packages/debril/feed-io)[ Docs](https://feed-io.net)[ RSS](/packages/debril-feed-io/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (155)Used By (7)

feed-io
=======

[](#feed-io)

Please use `php-feed-io/feed-io`
--------------------------------

[](#please-use-php-feed-iofeed-io)

Important

`feed-io` has now a dedicated organization to take care of its maintenance. Please head to  for documentation, questions, feature requests and bug reports. Huge thanks to everyone who contributed so far to make `feed-io` this tiny library I'm so proud of. Especially to [@Grotax](https://github.com/Grotax) and [@SMillerDev](https://github.com/SMillerDev), without whom this journey couldn't continue. Big ups to you guys ! 🍻

[feed-io](https://github.com/php-feed-io/feed-io) is a PHP library built to consume and serve news feeds. It features:

- JSONFeed / Atom / RSS read and write support
- Feeds auto-discovery through HTML headers
- a Command line interface to discover and read feeds
- PSR-7 Response generation with accurate cache headers
- HTTP Headers support when reading feeds in order to save network traffic
- Detection of the format (RSS / Atom) when reading feeds
- Enclosure support to handle external medias like audio content
- Feed logo support (RSS + Atom)
- PSR compliant logging
- Content filtering to fetch only the newest items
- DateTime detection and conversion
- A generic HTTP ClientInterface
- Integrates with every [PSR-18 compatible HTTP client](https://www.php-fig.org/psr/psr-18/).

Note

This feature list may become outdated with new versions of `php-feed-io/feed-io`.

This library is highly extensible and is designed to adapt to many situations, so if you don't find a solution through the documentation feel free to ask in the [discussions](https://github.com/php-feed-io/feed-io/discussions).

Installation
============

[](#installation)

Use Composer to add feed-io into your project's requirements :

```
    composer require php-feed-io/feed-io
```

Requirements
============

[](#requirements)

feed-ioPHP4.x7.1+5.08.0+6.08.1+feed-io 4 requires PHP 7.1+, feed-io 5 requires PHP 8.0+. All versions relies on `psr/log` and any PSR-18 compliant HTTP client. To continue using you may require `php-http/guzzle7-adapter`. it suggests `monolog` for logging. Monolog is not the only library suitable to handle feed-io's logs, you can use any PSR/Log compliant library instead.

Usage
=====

[](#usage)

CLI
---

[](#cli)

Let's suppose you installed feed-io using Composer, you can use its command line client to read feeds from your terminal :

```
./vendor/bin/feedio read http://php.net/feed.atom
```

reading
-------

[](#reading)

feed-io is designed to read feeds across the internet and to publish your own. Its main class is [FeedIo](https://github.com/alexdebril/feed-io/blob/master/src/FeedIo/FeedIo.php) :

```
// create a simple FeedIo instance, e.g. with the Symfony HTTP Client
$client = new \FeedIo\Adapter\Http\Client(new Symfony\Component\HttpClient\HttplugClient());
$feedIo = \FeedIo\FeedIo($client);

// read a feed
$result = $feedIo->read($url);

// get title
$feedTitle = $result->getFeed()->getTitle();

// iterate through items
foreach( $result->getFeed() as $item ) {
    echo $item->getTitle();
}
```

If you need to get only the new items since the last time you've consumed the feed, use the result's `getItemsSince()` method:

```
// read a feed and specify the `$modifiedSince` limit to fetch only items newer than this date
$result = $feedIo->read($url, $feed, $modifiedSince);

// iterate through new items
foreach( $result->getItemsSince() as $item ) {
    echo $item->getTitle();
}
```

You can also mix several filters to exclude items according to your needs:

```
// read a feed
$result = $feedIo->read($url, $feed, $modifiedSince);

// remove items older than `$modifiedSince`
$since = new FeedIo\Filter\Since($result->getModifiedSince());

// Your own filter
$database = new Acme\Filter\Database();

$chain = new Chain();
$chain
    ->add($since)
    ->add($database);

// iterate through new items
foreach( $result->getFilteredItems($chain) as $item ) {
    echo $item->getTitle();
}
```

In order to save bandwidth, feed-io estimates the next time it will be relevant to read the feed and get new items from it.

```
$nextUpdate = $result->getNextUpdate();
echo "computed next update: {$nextUpdate->format(\DATE_ATOM)}";

// you may need to access the statistics
$updateStats = $result->getUpdateStats();
echo "average interval in seconds: {$updateStats->getAverageInterval()}";
```

feed-io calculates the next update time by first detecting if the feed was active in the last 7 days and if not we consider it as sleepy. The next update date for a sleepy feed is set to the next day at the same time. If the feed isn't sleepy we use the average interval and the median interval by adding those intervals to the feed's last modified date and compare the result to the current time. If the result is in the future, then it's returned as the next update time. If none of them are in the future, we considered the feed will be updated quite soon, so the next update time is one hour later from the moment of the calculation.

Please note: the fixed delays for sleepy and closed to be updated feeds can be set through `Result::getNextUpdate()` arguments, see [Result](src/FeedIo/Reader/Result.php) for more details.

Feeds discovery
---------------

[](#feeds-discovery)

A web page can refer to one or more feeds in its headers, feed-io provides a way to discover them :

```
// create a simple FeedIo instance, e.g. with the Symfony HTTP Client
$client = new \FeedIo\Adapter\Http\Client(new Symfony\Component\HttpClient\HttplugClient());
$feedIo = \FeedIo\FeedIo($client);

$feeds = $feedIo->discover($url);

foreach( $feeds as $feed ) {
    echo "discovered feed : {$feed}";
}
```

Or you can use feed-io's command line :

```
./vendor/bin/feedio discover https://a-website.org
```

You'll get all discovered feeds in the output.

formatting an object into a XML stream
--------------------------------------

[](#formatting-an-object-into-a-xml-stream)

```
// build the feed
$feed = new FeedIo\Feed;
$feed->setTitle('...');

// convert it into Atom
$atomString = $feedIo->toAtom($feed);

// or ...
$atomString = $feedIo->format($feed, 'atom');
```

Adding a StyleSheet
-------------------

[](#adding-a-stylesheet)

```
$feed = new FeedIo\Feed;
$feed->setTitle('...');
$styleSheet = new StyleSheet('http://url-of-the-xsl-stylesheet.xsl');
$feed->setStyleSheet($styleSheet);
```

building a feed including medias
--------------------------------

[](#building-a-feed-including-medias)

```
// build the feed
$feed = new FeedIo\Feed;
$feed->setTitle('...');

$item = $feed->newItem();

// add namespaces
$feed->setNS(
    'itunes', //namespace
    'http://www.itunes.com/dtds/podcast-1.0.dtd' //dtd for the namespace
        );
$feed->set('itunes,title', 'Sample Title'); //OR any other element defined in the namespace.
$item->addElement('itunes:category', 'Education');

// build the media
$media = new \FeedIo\Feed\Item\Media
$media->setUrl('http://yourdomain.tld/medias/some-podcast.mp3');
$media->setType('audio/mpeg');

// add it to the item
$item->addMedia($media);

$feed->add($item);
```

Creating a valid PSR-7 Response with a feed
-------------------------------------------

[](#creating-a-valid-psr-7-response-with-a-feed)

You can turn a `\FeedIo\FeedInstance` directly into a PSR-7 valid response using `\FeedIo\FeedIo::getPsrResponse()` :

```
$feed = new \FeedIo\Feed;

// feed the beast ...
$item = new \FeedIo\Feed\Item;
$item->set ...
$feed->add($item);

$atomResponse = $feedIo->getPsrResponse($feed, 'atom');

$jsonResponse = $feedIo->getPsrResponse($feed, 'json');
```

Building a FeedIo instance
--------------------------

[](#building-a-feedio-instance)

To create a new FeedIo instance you only need to inject two dependencies :

- an HTTP Client implementing FeedIo\\Adapter\\ClientInterface. It can be wrapper for an external library like FeedIo\\Adapter\\Guzzle\\Client
- a PSR-3 logger implementing Psr\\Log\\LoggerInterface

```
// first dependency : the HTTP client
// here we use Guzzle as a dependency for the client
$guzzle = new GuzzleHttp\Client();
// Guzzle is wrapped in this adapter which is a FeedIo\Adapter\ClientInterface  implementation
$client = new FeedIo\Adapter\Guzzle\Client($guzzle);

// second dependency : a PSR-3 logger
$logger = new Psr\Log\NullLogger();

// now create FeedIo's instance
$feedIo = new FeedIo\FeedIo($client, $logger);
```

Another example with Monolog configured to write on the standard output :

```
// create a simple FeedIo instance, e.g. with the Symfony HTTP Client
$client = new \FeedIo\Adapter\Http\Client(new Symfony\Component\HttpClient\HttplugClient());
$logger = new Monolog\Logger('default', [new Monolog\Handler\StreamHandler('php://stdout')]);
$feedIo = \FeedIo\FeedIo($client, $logger);
```

### Inject a custom Logger

[](#inject-a-custom-logger)

You can inject any Logger you want as long as it implements `Psr\Log\LoggerInterface`. Monolog does, but it's not the only library :

```
use FeedIo\FeedIo;
use FeedIo\Adapter\Guzzle\Client;
use GuzzleHttp\Client as GuzzleClient;
use Custom\Logger;

$client = new Client(new GuzzleClient());
$logger = new Logger();

$feedIo = new FeedIo($client, $logger);
```

### Inject a custom HTTP Client

[](#inject-a-custom-http-client)

Since 6.0 there is a generic HTTP adapter that wraps any PST-18 compliant HTTP client.

```
use CustomPsr18\Client as CustomClient;

$client = new Custom\Adapter\Http\Client(new CustomClient())
$logger = new Psr\Log\NullLogger();

$feedIo = new FeedIo\FeedIo($client, $logger);
```

Configure feed-io using the Factory
-----------------------------------

[](#configure-feed-io-using-the-factory)

The factory has been deprecated in feed-io 5.2 and was removed in 6.0. Instantiate the facade directly and pass in the desired HTTP client and logger interface.

Dealing with missing timezones
------------------------------

[](#dealing-with-missing-timezones)

Sometimes you have to consume feeds in which the timezone is missing from the dates. In some use-cases, you may need to specify the feed's timezone to get an accurate value, so feed-io offers a workaround for that :

```
$feedIo->getDateTimeBuilder()->setFeedTimezone(new \DateTimeZone($feedTimezone));
$result = $feedIo->read($feedUrl);
$feedIo->getDateTimeBuilder()->resetFeedTimezone();
```

Don't forget to reset `feedTimezone` after fetching the result, or you'll end up with all feeds located in the same timezone.

Built with PHP Storm
--------------------

[](#built-with-php-storm)

Most of feed-io's code was written using [PHP Storm](https://www.jetbrains.com/phpstorm/) courtesy of Jetbrains.

###  Health Score

60

—

FairBetter than 99% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity59

Moderate usage in the ecosystem

Community37

Small or concentrated contributor base

Maturity90

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 92% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~20 days

Recently: every ~99 days

Total

150

Last Release

937d ago

Major Versions

v4.9.13 → v5.1.02022-04-14

v4.9.14 → v5.3.02022-06-09

v5.3.0 → v6.0.02022-06-09

v4.9.15 → v5.3.12022-10-26

v5.3.1 → v6.0.32023-10-16

PHP version history (6 changes)v1.0.1PHP &gt;=5.4.0

v2.0.0PHP &gt;=5.5.0

v2.2.2PHP &gt;=5.6.0

v4.0.0-beta1PHP &gt;=7.1

v5.0.0-beta2PHP &gt;=8.0

v6.0.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/ad37379f66794fd719e1e491f3c102114e686a89ff6d171b1f8c752b55a084b2?d=identicon)[adebril](/maintainers/adebril)

---

Top Contributors

[![alexdebril](https://avatars.githubusercontent.com/u/207048?v=4)](https://github.com/alexdebril "alexdebril (903 commits)")[![bezin](https://avatars.githubusercontent.com/u/4400435?v=4)](https://github.com/bezin "bezin (19 commits)")[![azmeuk](https://avatars.githubusercontent.com/u/60163?v=4)](https://github.com/azmeuk "azmeuk (8 commits)")[![sylvainlg](https://avatars.githubusercontent.com/u/568835?v=4)](https://github.com/sylvainlg "sylvainlg (6 commits)")[![mirfilip](https://avatars.githubusercontent.com/u/1812341?v=4)](https://github.com/mirfilip "mirfilip (6 commits)")[![leonghui](https://avatars.githubusercontent.com/u/6092315?v=4)](https://github.com/leonghui "leonghui (5 commits)")[![luispabon](https://avatars.githubusercontent.com/u/6388823?v=4)](https://github.com/luispabon "luispabon (4 commits)")[![kesselb](https://avatars.githubusercontent.com/u/3902676?v=4)](https://github.com/kesselb "kesselb (4 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (3 commits)")[![davispuh](https://avatars.githubusercontent.com/u/651800?v=4)](https://github.com/davispuh "davispuh (2 commits)")[![boris-glumpler](https://avatars.githubusercontent.com/u/580004?v=4)](https://github.com/boris-glumpler "boris-glumpler (2 commits)")[![marijnotte](https://avatars.githubusercontent.com/u/6791447?v=4)](https://github.com/marijnotte "marijnotte (1 commits)")[![OskarStark](https://avatars.githubusercontent.com/u/995707?v=4)](https://github.com/OskarStark "OskarStark (1 commits)")[![PhilETaylor](https://avatars.githubusercontent.com/u/400092?v=4)](https://github.com/PhilETaylor "PhilETaylor (1 commits)")[![richhl](https://avatars.githubusercontent.com/u/1074446?v=4)](https://github.com/richhl "richhl (1 commits)")[![shempignon](https://avatars.githubusercontent.com/u/11563817?v=4)](https://github.com/shempignon "shempignon (1 commits)")[![SMillerDev](https://avatars.githubusercontent.com/u/1484494?v=4)](https://github.com/SMillerDev "SMillerDev (1 commits)")[![tacovandenbroek](https://avatars.githubusercontent.com/u/1499481?v=4)](https://github.com/tacovandenbroek "tacovandenbroek (1 commits)")[![AccaliaDeElementia](https://avatars.githubusercontent.com/u/829476?v=4)](https://github.com/AccaliaDeElementia "AccaliaDeElementia (1 commits)")[![tnorthcutt](https://avatars.githubusercontent.com/u/796639?v=4)](https://github.com/tnorthcutt "tnorthcutt (1 commits)")

---

Tags

atomfeedfeed-iojsonfeedphpphp-librarypsrrssclientcliatomfeedrss newsjsonfeed

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/debril-feed-io/health.svg)

```
[![Health](https://phpackages.com/badges/debril-feed-io/health.svg)](https://phpackages.com/packages/debril-feed-io)
```

###  Alternatives

[php-feed-io/feed-io

PHP library built to consume and serve JSONFeed / RSS / Atom feeds

15218.4k8](/packages/php-feed-io-feed-io)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[league/climate

PHP's best friend for the terminal. CLImate allows you to easily output colored text, special formats, and more.

1.9k14.0M273](/packages/league-climate)[opensearch-project/opensearch-php

PHP Client for OpenSearch

15224.3M65](/packages/opensearch-project-opensearch-php)[debril/rss-atom-bundle

RSS / Atom and JSONFeed support for Symfony

1381.3M2](/packages/debril-rss-atom-bundle)[bnomei/kirby3-feed

Generate a Atom/JSON/RSS-Feed and XML-Sitemap from Pages-Collections

7224.8k](/packages/bnomei-kirby3-feed)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
