PHP:DOMDocument::load(): I/O 警告:无法加载外部实体(外部 rss 提要和缓存文件)
PHP:DOMDocument::load(): I/O warning : failed to load external entity (external rss feed and cache file)
我需要在我的页面上显示来自外部 RSS 提要的最新条目。
我制作了一个使用缓存文件的简单 rss reader。
它在我的测试环境中完美运行,但是当我把它放在我的网站上时,每次必须写入缓存文件时我都会出错:
警告:DOMDocument::load():I/O 警告:无法在 .../[= 中加载外部实体“.../rssRadio.xml.cache” 34=] 第 45 行
这是页面的代码。第 45 行是最后一行:
$cacheName = 'cache/rss.xml.cache';
$ageInSeconds = (3600*2); // two hour
if(!file_exists($cacheName) || filemtime($cacheName) < time() - $ageInSeconds ) {
$contents = file_get_contents($RSSURL);
file_put_contents($cacheName, $contents);
}
$rss = new DOMDocument();
if (!$rss->load($cacheName)) {
throw new Exception('Impossibile caricare i podcast');
}
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
...
如果我重新加载页面,错误消失并显示内容,所以缓存文件工作正常。
看起来它正在尝试在 file_put_contents 调用结束之前读取缓存文件的脚本。但这是不可能的,因为这是一个阻塞的 I/O 调用……对吧?
有什么想法吗?
干杯
问题可能出在服务器延迟更新索引树上。您可以在 file_put_contents
之后添加 usleep(100);
来解决它。
但是,在我看来,最好的解决方案是这样的:
if(!file_exists($cacheName) || filemtime($cacheName) < time() - $ageInSeconds )
{
$contents = file_get_contents( $RSSURL );
file_put_contents( $cacheName, $contents );
}
else
{
$contents = file_get_contents( $cacheName );
}
$rss = new DOMDocument();
if( !$rss->loadXML( $contents ) )
{
throw new Exception( 'Impossibile caricare i podcast' );
}
通过这种方式,您加载的是字符串而不是文件,您的脚本将正常运行。
我需要在我的页面上显示来自外部 RSS 提要的最新条目。 我制作了一个使用缓存文件的简单 rss reader。
它在我的测试环境中完美运行,但是当我把它放在我的网站上时,每次必须写入缓存文件时我都会出错:
警告:DOMDocument::load():I/O 警告:无法在 .../[= 中加载外部实体“.../rssRadio.xml.cache” 34=] 第 45 行
这是页面的代码。第 45 行是最后一行:
$cacheName = 'cache/rss.xml.cache'; $ageInSeconds = (3600*2); // two hour if(!file_exists($cacheName) || filemtime($cacheName) < time() - $ageInSeconds ) { $contents = file_get_contents($RSSURL); file_put_contents($cacheName, $contents); } $rss = new DOMDocument(); if (!$rss->load($cacheName)) { throw new Exception('Impossibile caricare i podcast'); } $feed = array(); foreach ($rss->getElementsByTagName('item') as $node) {
...
如果我重新加载页面,错误消失并显示内容,所以缓存文件工作正常。
看起来它正在尝试在 file_put_contents 调用结束之前读取缓存文件的脚本。但这是不可能的,因为这是一个阻塞的 I/O 调用……对吧? 有什么想法吗?
干杯
问题可能出在服务器延迟更新索引树上。您可以在 file_put_contents
之后添加 usleep(100);
来解决它。
但是,在我看来,最好的解决方案是这样的:
if(!file_exists($cacheName) || filemtime($cacheName) < time() - $ageInSeconds )
{
$contents = file_get_contents( $RSSURL );
file_put_contents( $cacheName, $contents );
}
else
{
$contents = file_get_contents( $cacheName );
}
$rss = new DOMDocument();
if( !$rss->loadXML( $contents ) )
{
throw new Exception( 'Impossibile caricare i podcast' );
}
通过这种方式,您加载的是字符串而不是文件,您的脚本将正常运行。