现在 FeedSky 已经完全不行了,托管的 Feed 地址也没办法访问,之前写《Feed 托管服务商的选择与使用技巧》和《WordPress Feed 美化及订阅统计》时,虽然不是很稳定,但凑合着可以用。就现在的状况来看,是时候把自定义的 Feed 域名换个地方托管了,并且通过SAE 高级开发者后,每月送的云豆也用不完,就琢磨着把 Feed 域名解析到 SAE 上。
在《Feed 托管服务商的选择与使用技巧》中,已经介绍过在自己空间通过子域名托管自定义域名的方法,很简单的几步。首先在主机上添加一个子域名,作为 Feed 订阅地址,如:feed.xuhehuan.com;然后再空间上建立一个名为 index.php 的文件,内容如下:
<?php header("Content-Type: application/xml; charset=utf-8") ; @readfile(https://xuhehuan.com/feed); ?>
在 SAE 中,@readfile 是没办法使用了,不过有不少替代的方法,实现起来同样非常简单。首先在 SAE 的控制台中新建一个应用来托管 Feed,然后绑定域名,最后新建一个 index.php 的文件放到应用的目录下,建立 index.php 的方法不止一种,下面是我试过的几个,可以选择一个根据情况修改使用,记得把里面的’https://xuhehuan.com/feed 换成你的 feed 地址。
一、初级篇
方法一:使用 SaeFetchurl(SAE 专用)
<?php header("Content-Type: text/xml; charset=utf-8") ; $url="https://xuhehuan.com/feed"; $f = new SaeFetchurl(); $content = $f->fetch($url); echo $content; ?>
方法二:使用 file_get_contents(普通主机也适用)
<?php header("Content-Type: text/xml; charset=utf-8") ; $url="https://xuhehuan.com/feed"; $content= file_get_contents($url); echo $content; ?>
方法三:使用 curl(普通主机也适用)
<?php header("Content-Type: text/xml; charset=utf-8") ; $url="https://xuhehuan.com/feed"; $header[] = "Content-type: text/xml;"; // 定义 content-type 为 xml $ch=curl_init(); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $header);// 定义请求类型 curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); // 定义是否直接输出返回流 $content=curl_exec($ch); if(curl_errno($ch)){ echo curl_error($ch); curl_close($ch); } else { curl_close($ch); echo $content; } ?>
二、进阶篇
如果你用的是原生的 wordpress feed 输出地址,上面的代码应该就可以应付了,但如果 SAE 抓取你主机的访问速度比较慢,很可能会出现 feed 输出内容没抓全的问题,以 SaeFetchurl 来说,就有这样的服务限制:
默认超时时间:
- 连接超时: 5 秒
- 发送数据超时: 30 秒
- 接收数据超时: 40 秒
这时就要根据情况增大抓取链接允许的超时限制了,为此以上三个方法可以分别修改为:
方法一:使用 SaeFetchurl(SAE 专用)
<?php header("Content-Type: text/xml; charset=utf-8") ; $url="https://xuhehuan.com/feed"; $f = new SaeFetchurl(); $f->setConnectTimeout(20000); // 以毫秒为单位,必须小于 SAE 系统设置的时间, 否则以 SAE 系统设置为准(默认为 20 秒) $content = $f->fetch($url); if ($content === false) var_dump($f->errno(), $f->errmsg()); else echo $content; ?>
方法二:使用 file_get_contents(普通主机也适用)
<?php header("Content-Type: text/xml; charset=utf-8") ; $url="https://xuhehuan.com/feed"; $opts = array( 'http'=>array( 'method'=>"GET", 'timeout'=>20, // 以秒为单位 ) ); $context = stream_context_create($opts); $content= file_get_contents($url, false, $context); echo $content; ?>
方法三:使用 curl(普通主机也适用)
<?php header("Content-Type: text/xml; charset=utf-8") ; $url="https://xuhehuan.com/feed"; $header[] = "Content-type: text/xml;"; $ch=curl_init(); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20000); // 以毫秒为单位,在发起连接前等待的时间,如果设置为 0,则无限等待 $content=curl_exec($ch); if(curl_errno($ch)){ echo curl_error($ch); curl_close($ch); } else { curl_close($ch); echo $content; } ?>
这样基本解决了抓取显示的问题,就是查看时可能需要多等待些时间。
三、进阶篇
接下来进行更深一步的优化,用 SAE 的 cron 服务将需要抓取的 url 事先生成好放到 storage 或 kvdb 中,从而节省抓取时间,加快访问速度。这里仅以 SAE 应用为例,其它情况请自行参考。为此,首先在 config.yaml 文件中增加下面几句:
cron: - description: curl feed xml file url: /feed.php schedule: every day of month 03:00
然后在根目录新建 feed.php,实现抓取网站 feed 的 url 生成 xml 文件到 storage 中(当然用 kvdb 也行),这样每天凌 3 点都会更新网站的 xml 文件到 SAE 应用下面,由于这个 feed.php 不是直接展示给用户的,因此不用在意等待时间,只需保证 xml 文件生成正确就行。feed.php 内容如下,请根据情况修改备份域和抓取的 feed 地址:
<?php /********************************************************************************* **** 为网站的 Feed 生成 xml 文件并存储到 storage 下 (By xhhjin: https://xuhehuan.com) **** *********************************************************************************/ define('DB_DOMAIN','cdn'); // 备份域 $url='https://xuhehuan.com/feed'; // 抓取的 feed 地址 $pathname = 'feed/rss.xml'; // 存储的 feed 文件 header('Content-Type: text/xml; charset=UTF-8'); $opts = array( 'http'=>array( 'method'=>"GET", 'timeout'=>20, // 以秒为单位 ) ); $context = stream_context_create($opts); $cnt=0; while($cnt<5 && ($content=file_get_contents($url, false, stream_context_create($opts)))===FALSE) $cnt++; $stor = new SaeStorage(); $stor->write(DB_DOMAIN, $pathname, $content); echo $content; ?>
这里通过增加连接等待时间和失败时多次重试的方法来尽量保证网站 feed 对应 xml 文件生成的正确性。最后一步就是修改网站根目录的 index.php 文件了,让它直接读取 SAE 上的 xml 文件显示,不用再次访问网站 feed。修改如下:
<?php header("Content-Type: text/xml; charset=utf-8") ; header('Pragma: no-cache'); // 兼容 HTTP/1.0 和 https header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP/1.1 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); $url="http://mancao-feed.stor.sinaapp.com/feed/rss.xml"; // 替换为你的正确的地址 $content= file_get_contents($url); echo $content; ?>
教程结束,再次访问下自定义的 feed 域名地址,感觉好很多了吧 :)
后记,后面使用时发现,有时访问会出现 XML 访问不全或 Chrome 下访问出现空白的问题,目前还没有找到办法解决。
欢迎转载,转载请注明出处:蔓草札记 » 用 SAE 托管 WordPress 网站 Feed 地址