A modern, framework-agnostic PHP Feed generator for Laravel, Symfony, and any PHP project. Generate RSS and Atom feeds with full caching support and customizable views.
- π Framework Agnostic: Works with Laravel, Symfony, or any PHP project
- π‘ Multiple Formats: RSS 2.0 and Atom 1.0 support
- β‘ Caching: Built-in caching support with framework adapters
- π¨ Custom Views: Use your own templates for feed generation
- π§ Dependency Injection: Clean architecture with adapter pattern
- β 100% Test Coverage: Thoroughly tested with Pest
- π PSR-12 Compliant: Follows modern PHP standards
- π Type Safe: Full PHP 8.3+ type declarations
- PHP 8.3+
- Composer
composer require rumenx/php-feed
Basic Usage:
use Rumenx\Feed\FeedFactory;
class FeedController extends Controller
{
public function feed()
{
$feed = FeedFactory::create();
$feed->setTitle('My Blog Feed');
$feed->setDescription('Latest posts from my blog');
$feed->setLink('https://example.com');
$feed->addItem([
'title' => 'First Post',
'author' => 'Rumen',
'link' => 'https://example.com/post/1',
'pubdate' => now(),
'description' => 'This is the first post.'
]);
// Return XML string directly
$xml = $feed->render('rss');
return response($xml, 200, [
'Content-Type' => 'application/xml'
]);
}
}
Using Laravel Views (Optional):
For more control, you can use the included Blade templates:
use Rumenx\Feed\FeedFactory;
class FeedController extends Controller
{
public function feed()
{
$feed = FeedFactory::create();
$feed->setTitle('My Blog Feed');
$feed->addItem([
'title' => 'First Post',
'author' => 'Rumen',
'link' => 'https://example.com/post/1',
'pubdate' => now(),
'description' => 'This is the first post.'
]);
// Get data for your own view template
$items = $feed->getItems();
$channel = [
'title' => $feed->getTitle(),
'description' => $feed->getDescription(),
'link' => $feed->getLink()
];
return response()->view('feed.rss', compact('items', 'channel'), 200, [
'Content-Type' => 'application/xml'
]);
}
}
Basic Usage:
use Rumenx\Feed\FeedFactory;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class FeedController extends AbstractController
{
public function feed(): Response
{
$feed = FeedFactory::create();
$feed->setTitle('My Blog Feed');
$feed->setDescription('Latest posts from my blog');
$feed->setLink('https://example.com');
$feed->addItem([
'title' => 'First Post',
'author' => 'Rumen',
'link' => 'https://example.com/post/1',
'pubdate' => new \DateTime(),
'description' => 'This is the first post.'
]);
// Return XML response
$xml = $feed->render('atom');
return new Response($xml, 200, ['Content-Type' => 'application/xml']);
}
}
Using Symfony Views (Optional):
For more control, you can use Twig templates:
class FeedController extends AbstractController
{
public function feed(): Response
{
$feed = FeedFactory::create();
$feed->setTitle('My Blog Feed');
$feed->addItem([
'title' => 'First Post',
'author' => 'Rumen',
'link' => 'https://example.com/post/1',
'pubdate' => new \DateTime(),
'description' => 'This is the first post.'
]);
// Get data for your own Twig template
$items = $feed->getItems();
$channel = [
'title' => $feed->getTitle(),
'description' => $feed->getDescription(),
'link' => $feed->getLink()
];
return $this->render('feed/atom.xml.twig', [
'items' => $items,
'channel' => $channel
], new Response('', 200, ['Content-Type' => 'application/xml']));
}
}
Simple Usage (Recommended):
require 'vendor/autoload.php';
use Rumenx\Feed\FeedFactory;
// Create feed with simple built-in adapters
$feed = FeedFactory::create();
$feed->setTitle('My Feed');
$feed->setDescription('Feed description');
$feed->setLink('https://example.com');
$feed->addItem([
'title' => 'Hello World',
'author' => 'Rumen',
'link' => 'https://example.com/hello',
'pubdate' => date('c'),
'description' => 'Hello world post!'
]);
// Output RSS feed
header('Content-Type: application/xml');
echo $feed->render('rss');
Advanced - Custom Adapters:
You can provide your own implementations for cache, config, response, and view:
use Rumenx\Feed\Feed;
$feed = new Feed([
'cache' => new MyCacheAdapter(),
'config' => new MyConfigAdapter(),
'response' => new MyResponseAdapter(),
'view' => new MyViewAdapter(),
]);
$feed->setTitle('My Feed');
$feed->addItem([
'title' => 'Hello',
'author' => 'Rumen',
'link' => 'https://example.com/hello',
'pubdate' => date('c'),
'description' => 'Hello world!'
]);
// Use render() for framework-specific response
// or render() for XML string in plain PHP
echo $feed->render('rss');
# Run tests
composer test
# Run tests with coverage
composer test:coverage
# Run tests with HTML coverage report
composer test:coverage-html
# Watch tests (automatically re-run on file changes)
composer test:watch
# Static analysis with PHPStan
composer analyse
# Check code style (PSR-12)
composer style
# Fix code style automatically
composer style:fix
# Run all checks (tests + analysis + style)
composer check
# Run CI checks (coverage + analysis + style)
composer ci
// Create feed with simple adapters (recommended for most users)
$feed = FeedFactory::create($config);
// Feed configuration
$feed->setTitle(string $title): self
$feed->setDescription(string $description): self
$feed->setLink(string $link): self
$feed->setDateFormat(string $format): self
$feed->setLanguage(string $language): self
// Item management
$feed->addItem(array $item): self
$feed->addItems(array $items): self
// Rendering
$feed->render(string $format = 'rss'): mixed // Returns framework-specific response or XML string
// Caching
$feed->isCached(string $key): bool
$feed->clearCache(string $key): self
This package follows a clean architecture pattern with dependency injection:
- Feed: Core feed generator class
- Adapters: Framework-specific implementations
FeedCacheInterface
: Caching operationsFeedConfigInterface
: Configuration accessFeedResponseInterface
: HTTP response handlingFeedViewInterface
: Template rendering
If you find this project useful, please consider supporting its development:
Other ways to support:
- β Star this repository
- π Report bugs and suggest improvements
- π» Contribute code or documentation
- π Make a donation - See FUNDING.md for details
We welcome contributions! Please see our Contributing Guide for details.
If you discover any security-related issues, please check our Security Policy.
This package is open-sourced software licensed under the MIT License.