PHP后台调用其他页面

有时候有个页面需要经常执行,比如备份或者更新缓存之类的操作,如果直接把代码写到主页,这样虽然每次访问就会执行,但是如果这个操作需要很长的时间的话,那么就会让页面打开非常慢,这种情况显然是不希望碰到的.

那么有没有办法打开页面就调用另一个页面,但是不需要等他返回信息呢?

也就是相当与我去敲别人门(调用页面),正常的流程我会等一会直到有人开门(返回结果)或者没人开门(超时).

然而现在我要敲完门就不管了直接走人……至于有没有人开门我不需要关心.^-^!!

问了一些人,也查了一些资料,得到了一个方法,使用fsockopen,向指定页面发送GET请求,然后不需要去读取返回内容!

//PHP CODE:
$fp = fsockopen($_SERVER["HTTP_HOST"], 80, $errno, $errmsg);
if(!$fp) {
    echo "$errstr ($errno)<br>rn";
} else {
    fputs($fp,"GET /index.php HTTP/1.0rnHost: $hostrnrn");
    fclose($fp);
}

加上一点简单的说明:
fsockopen 打开一个连接,主机$_SERVER[“HTTP_HOST”],即执行代码的服务器地址,端口 80,后面两个是错误信息.

如果连接成功,就向该主机的写入GET /index.php HTTP/1.0rnHost: $hostrnrn,这实际就是请求index.php页面,

然后关闭连接.

如果在fputs后面加fread,就可以看到返回的信息,即正常访问index.php看到的页面内容还有header信息!

wordpress显示腾讯微博信息

wordpress没有类似于微博的功能,只能发表文章,有时有个想法,或看到一个好句子或者想简洁的说说现在的状态,总不能全都是去发文章吧,于是想到了添加个类似微博的功能,一路坎坷,总算是完成了!!

接下来说说完成这个功能的经历:

1.最开始的想法是基于wordpress,完全独立做个简单微博功能,在数据库中添加一个微博的表,自己写发表和显示的功能.虽然说这样的难度不大,不过老是上wordpress来发表不太方便.而且以后维护好像也不方便,就放弃了这个方法.

2.利用腾讯微博的微博秀,这个最简单,腾讯微博开放平台可以申请,得到一个iframe页面,会显示微博信息,样式也可以设定,用了几天后实在受不了,连接速度实在太慢,这性能简直是在给腾讯抹黑啊…..再次放弃……

3.利用腾讯微博api,这个速度还不错,只是需要自己解析数据,可以返回json或者xml数据,于是准备用这种方法,不过我对js不了解,在获取远程数据上出了问题,于是打算用php实现,可是wordpress的widget不支持php代码,于是只能自己自定义一个widget来实现.

3.1首先是直接添加了一个自定义的widget,内部直接用php通过微博api获取微博的数据再显示出来,但是由于本站使用了wp super cache插件,这样的后果就是如果不刷新缓存文件,微博的信息就不会更新.

3.2于是想到widget的功能改为php获取信息后处理成可以显示的格式后保存到服务器上作为缓存文件,然后widget再用js的方式引用这个文件实现动态加载.由于本站还使用了wp minify插件,所以还得把这个js文件加入排除列表.于是这个功能就算是完成了!

3.3然后又考虑到了如果这个api调用速度问题,虽然现在看起来是很快,但是难保以后会不会出问题,于是想到了后台更新缓存文件.这暂时就是最终版.

具体流程就是自定义一个widget,他有两个工作,首先是使用后台的方法调用一个php页面,这个php页面负责更新缓存;再就是就是输出用js引用的方式调用缓存文件的代码.

然后辛苦完成了以后,悲剧了,这个功能可以简化,完全可以添加一个wordpress内置的文本widget,然后写上引用缓存文件的js代码就可以了,最后经过优化,写出了一个php文件,只需要在文本widget中用js引用调用这个php文件就可以完成信息加载和缓存的功能了.

附上该php代码:

//weibo.php
<?php
if($_GET["updata"]=="1"){
	date_default_timezone_set('PRC');
	$ch = curl_init("这里填写你的api url ,申请方法看下面") ;
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; 
	curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; 
	$json = json_decode(curl_exec($ch),true);
	$data= "<ul>";
	foreach($json[data][info] as $value){
	    if($value["text"]!=NULL){
	         $data.= "<li>".$value["text"]."<br/><font color=808080>".strftime("%Y-%m-%d %H:%M", $value[timestamp])."</font></li><hr>";
	    }
	}
	$data.= "</ul>";
	$data = "document.write("".str_replace(""", "\"", $data)."");";
	file_put_contents("weibo.cache",$data);
}else{
	echo file_get_contents("weibo.cache");
	$fp = fsockopen($_SERVER["HTTP_HOST"], 80, $errno, $errmsg);
	if(!$fp) {
		echo "$errstr ($errno)<br>rn";
	} else {
		fputs($fp,"GET $_GET[path]/weibo.php/?updata=1 HTTP/1.0rnHost: $hostrnrn");
		fclose($fp);
        }
}
?>

然后在文本widget中加入js代码:

<script type="text/javascript" src="主题路径/weibo.php/?path=主题路径"></script>

因为我把php文件放到主题目录里面了,所以上面需要加入主题路径,如果把php放到网站根目录,那么js代码就是:

<script type="text/javascript" src="/weibo.php"></script>

而weibo.php文件的代码也需要修改一处:

fputs($fp,"GET $_GET[path]/weibo.php/?update=1 HTTP/1.0rnHost: $hostrnrn");
//修改为
fputs($fp,"GET /weibo.php/?update=1 HTTP/1.0rnHost: $hostrnrn");

功能说明:

调用weibo.php后会读取目录下的weibo.cache文件,然后把它echo出来,之后weibo.php后台调用自己,不过加上了参数update=1,weibo.php发现update的值为1就会执行更新缓存weibo.cache的操作.

这个代码只是简单的显示了自己发的微博的文本内容,使用的api是https://open.t.qq.com/api/statuses/user_timeline?

完整的api请求可以到微博开放平台调试里面自动生成,API在线调试

步骤:

首先授权:

我选择的oAuth2.0授权(其他也可以,可能有些东西要改)

填入你自己的App Key 和 App Secret 确认授权,没申请应用的话暂时用这个页面默认的测试appkey也可以.

然后页面内填写:

fomat => json
reqnum => 填写你要拉取的微薄条数
name => 你要拉取的微博的id

然后点发送请求

下面有个header信息,GET后面 /api/statuses/user_timeline?….一直到HTTP/1.1 之间的部分记录下来,不包括HTTP/1.1
你的api地址就是https://open.t.qq.com/加上刚才记录的地址.
如果是另外两种授权方式就不是https , 而是http .

bug:

1.第一次读取会出错,因为读取在写入之前,所以是读的不存在的文件,刷新一次就正常显示了
2.同样由于先读后写,新的微博信息需要刷新2次才会显示.

之所以先读后写是为了避免一些问题,比如读的时候写操作还没完成……造成的这两个bug我觉得可以接受.

备选解决方案:

1.读取缓存前先判断缓存文件是否存在.

2.先写入缓存再读取显示.

另外在file_put_contents函数中可以加入LOCK_EX参数,锁定文件,避免可能发生的并发冲突,不过没测试锁定文件是否对读取造成影响,希望以后能找到更好的解决方案……

如果把缓存放到数据库,然后使用crontab定时更新缓存,这样缓存更新就和用户访问隔绝开了,应该是个比较好的解决方案!