SimplePie调用Feeds::make()触发unserialize错误,如何处理并获取RSS帖子?
解决SimplePie反序列化缓存文件时的报错问题
这个问题我之前排查过好几次,本质上是SimplePie的文件缓存在序列化/反序列化环节出了岔子——要么是Feed更新时缓存文件还没写完就被程序读取,要么是Feed本身带了些特殊字符搞坏了序列化数据。给你几个实用的解决思路,按优先级来:
1. 捕获错误并自动清理损坏缓存重试
PHP的Notice默认不会中断程序,但我们可以把这个特定的反序列化Notice转为可捕获的异常,然后删除损坏的缓存文件重新获取Feed:
// 临时将指定Notice转为Exception,方便捕获处理 set_error_handler(function($errno, $errstr) { if (strpos($errstr, 'unserialize(): Error at offset') !== false) { throw new RuntimeException($errstr); } return false; // 其他错误交给PHP默认处理 }); $maxRetries = 2; $retryCount = 0; $rssPosts = null; while ($retryCount < $maxRetries && $rssPosts === null) { try { $rssPosts = Feeds::make($rssFeedUrl, 100); } catch (RuntimeException $e) { // 定位并删除该Feed对应的损坏缓存文件 $feed = new SimplePie(); $feed->set_feed_url($rssFeedUrl); $cache = $feed->get_cache(); if ($cache instanceof SimplePie_Cache_File && file_exists($cache->location)) { unlink($cache->location); } $retryCount++; } } // 恢复默认错误处理逻辑 restore_error_handler();
这个方案能快速解决“偶尔出现”的缓存损坏问题,重试一次基本就能拿到正常的Feed内容。
2. 更换缓存驱动,避开文件缓存的坑
文件缓存很容易因为磁盘IO延迟、并发写入等问题导致文件损坏,换成内存缓存(比如APC、Redis)或者数据库缓存能从根源减少这类问题:
// 手动初始化SimplePie,改用APC缓存(需服务器支持APC扩展) $feed = new SimplePie(); $feed->set_feed_url($rssFeedUrl); $feed->set_cache_location('apc'); // 指定缓存驱动为APC $feed->set_cache_duration(3600); // 设置缓存有效期1小时 $feed->init(); $feed->handle_content_type(); $rssPosts = $feed->get_items(0, 100);
如果你的环境支持Redis,也可以配置SimplePie_Cache_Redis来使用,性能和稳定性会更好。
3. 预处理Feed内容,清理特殊字符
如果是Feed本身包含不可见控制字符导致序列化失败,可以先获取原始Feed内容并清理后再交给SimplePie:
// 获取原始Feed内容 $rawFeed = file_get_contents($rssFeedUrl); // 移除可能干扰序列化的控制字符(如\x00-\x1F这类不可见字符) $rawFeed = preg_replace('/[\x00-\x1F\x7F]/u', '', $rawFeed); // 将清理后的内容交给SimplePie处理 $feed = new SimplePie(); $feed->set_raw_data($rawFeed); $feed->init(); $feed->handle_content_type(); $rssPosts = $feed->get_items(0, 100);
这个方法适合那些本身内容有小问题的Feed,提前清理能避免后续序列化出错。
4. 升级SimplePie到最新稳定版
旧版本的SimplePie可能存在序列化相关的bug,建议用Composer更新到最新版:
composer update simplepie/simplepie
官方后续版本可能已经修复了这类缓存文件损坏的问题。
内容的提问来源于stack exchange,提问作者space_food_
相关产品推荐
相关产品推荐

