Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Feeds Laravel Package

willvincent/feeds

Laravel package for reading and creating RSS and Atom feeds with a simple, expressive API. Parse external feeds into structured items or generate your own from arrays, models, and custom views, with caching and Laravel integration built in.

Deep Wiki
Context7

Getting Started

Install via Composer and let Laravel's package auto-discovery register the service provider and Feeds facade (no manual entry in config/app.php needed on 5.5+ or 6–11+):

composer require willvincent/feeds

Optionally publish the config so you can tune SimplePie caching:

php artisan vendor:publish --provider="willvincent\Feeds\FeedsServiceProvider"

That drops a config/feeds.php containing cache enable/duration/location settings. If you're not sure what's in it, read the file first — the shipped keys are the only knobs SimplePie sees by default, and everything else is passed at call time.

First use case — pull a blog's feed and render it:

use willvincent\Feeds\Facades\FeedsFacade;

$feed = FeedsFacade::make('https://example.com/feed.xml');

if ($feed->error()) {
    // handle: log, fall back, return empty collection
}

foreach ($feed->get_items() as $item) {
    echo $item->get_title();
    echo $item->get_permalink();
    echo $item->get_description();
    echo $item->get_date('Y-m-d H:i:s');
}

The facade talks straight through to SimplePie. Everything on the returned object (get_title(), get_permalink(), get_image_url(), get_items()) and on each item (get_title(), get_content(), get_date(), get_author(), get_enclosure()) is SimplePie's own API — the package is a thin wrapper, not a re-abstraction. So the fastest path is: get the facade working, then read the SimplePie docs for anything beyond fetching items.

Implementation Patterns

Cache aggressively at the SimplePie layer. The make() signature takes ($url, $cacheDuration = null, $cacheEnabled = null, $options = []). Pass a duration in seconds; SimplePie will write a cached copy and skip the HTTP round-trip inside that window:

$feed = FeedsFacade::make($url, 3600, true); // 1 hour

This is fine for a single server. For multi-node deployments, point the cache location at a shared volume or disable it and use Laravel's cache instead.

Persist items, then read from the database. The typical production pattern is a scheduled artisan command that fetches, normalizes into an articles (or feed_items) table, and the frontend never touches SimplePie:

// app/Console/Commands/ImportFeeds.php
foreach (FeedSource::where('active', true)->cursor() as $source) {
    $feed = FeedsFacade::make($source->url, 1800, true);
    if ($feed->error()) {
        $source->update(['last_error' => implode(PHP_EOL, (array) $feed->error())]);
        continue;
    }

    foreach ($feed->get_items() as $item) {
        Article::updateOrCreate(
            ['guid' => $item->get_id()],
            [
                'feed_source_id' => $source->id,
                'title'          => $item->get_title(),
                'url'            => $item->get_permalink(),
                'summary'        => $item->get_description(),
                'content'        => $item->get_content(),
                'published_at'   => $item->get_date('Y-m-d H:i:s'),
                'author'         => optional($item->get_author())->getName(),
            ]
        );
    }
}

$item->get_id() is the right dedupe key when the feed provides one; fall back to hashing the permalink otherwise. Wrap each feed in its own try/catch inside the command so one broken source doesn't abort the run.

Controller/service usage — always guard errors first. $feed->error() returns false, a string, or an array of strings depending on how many problems SimplePie hits. Normalize it:

$errors = (array) $feed->error();
if ($errors) { /* handle */ }

Pass SimplePie options for anything non-default — user agent, timeouts, input encoding overrides:

$feed = FeedsFacade::make($url, 3600, true, [
    'set_useragent' => 'MyApp/1.0 (+https://myapp.test)',
    'set_timeout'   => 10,
    'set_stupidly_fast' => true,
]);

Keys are SimplePie setter names without the set_ prefix in newer wrapper versions — check the README for your installed version, since the exact pass-through has changed over releases.

Testing. Point the URL at a fixture file (file:///abs/path/fixture.xml) or a Storage::path() sample. That avoids network calls in CI and exercises the same parsing path. If you're mocking, mock the Feeds facade, not the underlying SimplePie classes.

Integration with Blade. Enclosures are the tricky bit for embedded media; always null-check:

@php $enclosure = $item->get_enclosure(); @endphp
@if ($enclosure && $enclosure->get_link())
    <img src="{{ $enclosure->get_link() }}" alt="">
@endif

Gotchas and Tips

Cache directory must exist and be writable. SimplePie writes to storage/framework/cache (or wherever you pointed it) and will fail silently-ish — surfaced via error() — if the path is missing. Add the directory to your deploy script. A common CI failure is running as a different user than the web server.

error() can lie. SimplePie may attach errors for non-fatal issues (unrecognized namespaces, minor XML quirks) while still returning usable items. Treat errors as advisory: log them, but check count($feed->get_items()) > 0 before deciding the fetch failed outright.

Date handling. get_date() returns a formatted string, not a Carbon instance. Pass 'U' for a Unix timestamp or 'Y-m-d H:i:s' for MySQL, then wrap in Carbon::parse() or Carbon::createFromTimestamp() if you need Carbon. Timezone info on the feed is respected by SimplePie but you're on your own after that.

Item arrays vs. iterators. get_items() returns an array, not a Collection. collect($feed->get_items()) is your friend if you want map/filter.

SSL and HTTP quirks. Self-signed certs, HTTP/2 redirects, or feeds behind Cloudflare will fail with cURL error strings in error(). You can pass set_curl_options through the options array, but disabling SSL verification is a footgun — prefer fixing the certificate or using a proxy.

SimplePie namespacing drift. Recent SimplePie releases (1.8+) moved classes under the SimplePie\ namespace, which broke older wrappers. If you see Class 'SimplePie' not found after a composer update, pin simplepie/simplepie to a compatible version or upgrade this package. Check the lock file when debugging — the wrapper's dependency bounds matter more than the wrapper's own changelog.

Don't fetch on every request. It's tempting to call FeedsFacade::make() inside a controller for a sidebar widget. Don't. Even with caching enabled you're paying filesystem stat checks and occasional re-fetches that add hundreds of ms to page load. Fetch in a scheduled job, store in the DB, read from the DB.

Long-running jobs and memory. SimplePie keeps parsed trees in memory. If you're importing dozens of feeds in one command, consider unset($feed) per iteration or run each feed as a separate queued job. For very large feeds, pass set_stupidly_fast => true to skip author/category parsing.

No pagination, no auth, no retries. This package will not paginate a feed, will not do OAuth, and will not retry failed fetches. Those are all on you. That's also why its "opportunity" score is low — it's a faithful wrapper, not a solution. If you're building a real feed-ingestion pipeline, expect to write the scheduling, dedupe, retry, and storage layers yourself; the package only owns the "fetch and parse XML" step.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource