Weave Code
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

Feed Io Laravel Package

php-feed-io/feed-io

feed-io is a PHP library for reading and writing RSS and Atom feeds. It handles fetching, parsing, and generating feed content with an easy-to-use API, making it simpler to consume external feeds or publish your own in PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require php-feed-io/feed-io
    

    Ensure your project meets PHP 8.1+ requirements (or 8.0+ for v5.x).

  2. Basic Initialization:

    use FeedIo\FeedIo;
    use FeedIo\Adapter\Guzzle\Client;
    use GuzzleHttp\Client as GuzzleClient;
    use Psr\Log\NullLogger;
    
    $httpClient = new Client(new GuzzleClient());
    $logger = new NullLogger();
    $feedIo = new FeedIo($httpClient, $logger);
    
  3. First Use Case: Fetch and parse a feed (e.g., RSS/Atom/JSONFeed):

    $result = $feedIo->read('https://example.com/feed.atom');
    echo $result->getFeed()->getTitle();
    

Key Entry Points

  • read(): Parse a feed URL into a Result object.
  • discover(): Extract feed links from HTML headers.
  • toAtom()/toJson(): Generate feed XML/JSON from a Feed object.
  • CLI: Run ./vendor/bin/feedio read <url> for quick testing.

Implementation Patterns

Core Workflows

1. Consuming Feeds

  • Filtering New Items:
    $modifiedSince = new DateTime('2023-01-01');
    $result = $feedIo->read($url, null, $modifiedSince);
    foreach ($result->getItemsSince($modifiedSince) as $item) {
        // Process new items
    }
    
  • Custom Filters:
    $chain = new FeedIo\Filter\Chain();
    $chain->add(new FeedIo\Filter\Since($modifiedSince));
    $chain->add(new Acme\Filter\Database()); // Custom filter
    foreach ($result->getFilteredItems($chain) as $item) {
        // Process filtered items
    }
    

2. Generating Feeds

  • Basic Feed Creation:
    $feed = new FeedIo\Feed();
    $feed->setTitle('My Blog');
    $item = $feed->newItem()->setTitle('New Post');
    $feed->add($item);
    
  • PSR-7 Response:
    $response = $feedIo->getPsrResponse($feed, 'atom');
    // Use with Laravel's HTTP responses:
    return new Response($response->getBody(), 200, $response->getHeaders());
    

3. Feed Discovery

  • From HTML Headers:
    $feeds = $feedIo->discover('https://example.com');
    foreach ($feeds as $feedUrl) {
        // Process discovered feeds
    }
    

4. Handling Media/Enclosures

  • Podcast/Video Feeds:
    $media = new FeedIo\Feed\Item\Media();
    $media->setUrl('https://example.com/audio.mp3')
          ->setType('audio/mpeg');
    $item->addMedia($media);
    

Laravel-Specific Patterns

Service Provider Integration

// config/feedio.php
return [
    'http_client' => \FeedIo\Adapter\Http\Client::class,
    'logger' => \Monolog\Logger::class,
];

// app/Providers/FeedIoServiceProvider.php
public function register()
{
    $this->app->singleton(FeedIo::class, function ($app) {
        $httpClient = new ($app['config']['feedio.http_client'])(new GuzzleHttp\Client());
        $logger = new ($app['config']['feedio.logger'])('feedio');
        return new FeedIo($httpClient, $logger);
    });
}

Queueing Feed Updates

// Dispatch a job to fetch and process feeds
FetchFeedsJob::dispatch($feedUrl)->onQueue('feeds');

Caching Feed Results

$cacheKey = "feed:{$url}:{$modifiedSince->getTimestamp()}";
$result = Cache::remember($cacheKey, now()->addHours(1), function () use ($feedIo, $url, $modifiedSince) {
    return $feedIo->read($url, null, $modifiedSince);
});

API Endpoints

// routes/api.php
Route::get('/feed/{url}', function ($url) {
    $feedIo = app(FeedIo::class);
    $result = $feedIo->read($url);
    return $feedIo->getPsrResponse($result->getFeed(), 'json');
});

Gotchas and Tips

Pitfalls

  1. Timezone Handling:

    • Feeds may omit timezones. Use feedIo->getDateTimeBuilder()->setFeedTimezone() temporarily:
      $feedIo->getDateTimeBuilder()->setFeedTimezone(new DateTimeZone('UTC'));
      $result = $feedIo->read($url);
      $feedIo->getDateTimeBuilder()->resetFeedTimezone(); // Reset to avoid side effects
      
  2. Redirect Loops:

    • The library handles redirects (301/302/307/308) but may fail on malformed URLs. Validate URLs before passing them to read().
  3. Invalid JSON/Atom:

    • Malformed feeds (e.g., invalid JSON) may throw exceptions. Use try-catch:
      try {
          $result = $feedIo->read($url);
      } catch (FeedIo\Exception\InvalidFeedException $e) {
          Log::error("Invalid feed at {$url}: " . $e->getMessage());
      }
      
  4. Media/Enclosure Issues:

    • Ensure type and url are set for media objects. Missing types may cause parsing errors.
  5. Filter Order:

    • Filters in a Chain are applied in order. Place Since filters early to avoid unnecessary processing.

Debugging Tips

  1. Enable Logging:

    • Use Monolog or Laravel’s logging to debug feed parsing:
      $logger = new Monolog\Logger('feedio', [
          new Monolog\Handler\StreamHandler(storage_path('logs/feedio.log'))
      ]);
      $feedIo = new FeedIo($client, $logger);
      
  2. Inspect Raw Responses:

    • Access the raw HTTP response for debugging:
      $result = $feedIo->read($url);
      $response = $result->getResponse();
      Log::debug($response->getBody());
      
  3. CLI Debugging:

    • Use the CLI tool to test feeds interactively:
      ./vendor/bin/feedio read --verbose https://example.com/feed
      

Extension Points

  1. Custom Feed Formats:

    • Extend FeedIo\Feed\FeedInterface to support custom formats (e.g., custom XML schemas).
  2. HTTP Client Adaptation:

    • Implement FeedIo\Adapter\ClientInterface for custom HTTP clients (e.g., Symfony’s HttpClient):
      use FeedIo\Adapter\Http\Client;
      $client = new Client(new Symfony\Component\HttpClient\HttplugClient());
      
  3. DateTime Handling:

    • Override FeedIo\DateTime\Builder to customize date parsing (e.g., for legacy feeds).
  4. Filter Extensions:

    • Create custom filters by implementing FeedIo\Filter\FilterInterface:
      class CustomFilter implements FilterInterface {
          public function filter(FeedItem $item, array $options): bool {
              return $item->getTitle() !== 'Excluded Post';
          }
      }
      
  5. PSR-7 Response Customization:

    • Extend FeedIo\FeedIo::getPsrResponse() to add headers or modify responses:
      $response = $feedIo->getPsrResponse($feed, 'atom');
      $response = $response->withHeader('X-Custom-Header', 'value');
      

Performance Optimizations

  1. Cache Headers:

    • Leverage getNextUpdate() to schedule feed refreshes:
      $nextUpdate = $result->getNextUpdate();
      Cache::put("feed:{$url}:next_update", $nextUpdate, $nextUpdate->diff(new DateTime()));
      
  2. Batch Processing:

    • Process multiple feeds in parallel using Laravel’s queues or jobs:
      foreach ($feedUrls as $url) {
          FetchFeedJob::dispatch($url)->onQueue('feeds');
      }
      
  3. Selective Fetching:

    • Use getModifiedSince() to avoid refetching unchanged feeds:
      $lastModified = Cache::get("feed:{$url}:last_modified");
      $result = $feedIo->read($url, null, $lastModified);
      Cache::put("feed
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity