应使用 feed-io/feed-io:^4.12.0 并手动注入 cURL 适配器,因 v5 要求 PHP ≥8.0 且强依赖 PSR-18/PSR-17,v4 支持 PHP 7.2+ 并自带轻量 HTTP 层,避免自动探测异常。

FeedIo 库不能直接通过 Composer 安装最新稳定版——因为它的主仓库已归档,官方推荐迁移到 feed-io/feedio(v5+),但 v5 不再兼容 PHP 7.x,且默认启用 PSR-18 强依赖,很多老项目会卡在 HTTP 客户端配置上。
为什么 composer require feed-io/feed-io 可能失败或行为异常
直接运行该命令常遇到两类问题:一是 PHP 版本不匹配(feed-io/feedio v5 要求 PHP >= 8.0),二是安装成功后调用 FeedIo::create() 报错 Class "Psr\Http\Client\ClientInterface" not found——这不是漏装包,而是 v5 强制要求你显式选一个 PSR-18 兼容的 HTTP 客户端(如 php-http/guzzle7-adapter 或 symfony/http-client)。
- v4.x 分支(
feed-io/feed-io:4.12.0)仍支持 PHP 7.2+,且自带轻量 HTTP 层,适合多数遗留项目 - 如果你用 Laravel 9+/Symfony 6+ 且 PHP ≥ 8.0,才建议走 v5 +
symfony/http-client组合 - 别用
dev-master:主仓库已归档,dev-main指向空分支,Composer 会报Could not find a matching version
PHP 7.2–7.4 项目应锁定 v4.12.0 并禁用自动 HTTP 客户端发现
v4 默认尝试自动探测已安装的 HTTP 库(如 Guzzle、cURL 封装器),但探测逻辑脆弱,容易误判或抛出未捕获异常。最稳的方式是显式传入 cURL 实例并关闭自动发现。
composer require feed-io/feed-io:^4.12.0
代码中初始化时避免使用静态工厂:
立即学习“PHP免费学习笔记(深入)”;
- ❌ 不要用
FeedIo::create()—— 它会触发自动客户端发现 - ✅ 改用构造函数手动注入:
new \FeedIo\FeedIo(new \FeedIo\Adapter\Curl(), new \FeedIo\Parser()) - 如果项目已装
guzzlehttp/guzzle,可改用new \FeedIo\Adapter\Guzzle(),但需确认 Guzzle 版本(v6/v7 均支持,v8 不兼容)
解析 Atom 订阅源时注意命名空间与日期格式差异
Atom 的 <updated> 和 RSS 的 <pubDate> 解析结果类型不同:FeedIo v4 默认将 Atom <updated> 解析为 DateTimeImmutable,而 RSS <pubDate> 是字符串(需手动 DateTime::createFromFormat())。若统一处理,建议强制标准化:
$feed = $feedIo->read('https://example.com/feed.atom');
foreach ($feed->getItems() as $item) {
// Atom: $item->getLastModified() 返回 DateTimeImmutable
// RSS: $item->getDate() 返回字符串,得自己 parse
$date = $item->getLastModified() ?: \DateTimeImmutable::createFromFormat(
'D, d M Y H:i:s O',
$item->getDate()
);
}
- 别依赖
$item->getDate()直接输出——它对 Atom 和 RSS 返回值类型不一致 - Atom 中
<id>字段映射到$item->getId(),RSS 中等效字段是<guid>,但 FeedIo v4 会把两者都塞进getId(),无需额外判断 - 如果源含 CDATA 包裹的 HTML 内容(常见于 RSS 描述),
$item->getDescription()返回的是已解码后的纯文本,原始 HTML 已丢失;需改用$item->getRawDescription()
v5 在 PHP 8.0+ 环境下的最小可行配置
若确定升级到 v5,必须补全 PSR-18 客户端和 PSR-17 工厂。仅装 symfony/http-client 不够,还得配 nyholm/psr7(提供 Request/Response 工厂):
composer require feed-io/feedio:^5.0 symfony/http-client nyholm/psr7
初始化代码必须显式传入三元组:
$httpClient = new \Symfony\Component\HttpClient\Psr18Client(); $requestFactory = new \Nyholm\Psr7\Factory\Psr17Factory(); $streamFactory = new \Nyholm\Psr7\Factory\Psr17Factory(); $feedIo = new \FeedIo\FeedIo($httpClient, $requestFactory, $streamFactory);
- 漏掉
$streamFactory会报ArgumentCountError: Too few arguments -
guzzlehttp/guzzle本身不提供 PSR-17 实现,必须额外装guzzlehttp/psr7或换用nyholm/psr7 - v5 移除了
FeedIo::create(),也没有降级回退机制——不配齐三个工厂,代码直接无法启动
真正麻烦的不是安装命令,而是 HTTP 客户端绑定方式的断裂变化:v4 把网络层当可选依赖,v5 当核心契约。如果你的部署环境不能保证 PHP 版本或无法控制扩展(比如共享主机只有 PHP 7.4 + cURL),v4.12.0 + 手动 Curl 适配器仍是更省心的选择。



















