最新消息:

php实现计划任务研究:ignore_user_abort()/set_time_limit()/sleep()

PHP admin 2285浏览 0评论

研究xsser.me跨站平台的keep-session时,发现xsser.me是将所有需要keep-session的cookie和url等信息存储到一个数据表中,然后定时使用获取的cookie来访问相应的url来保证cookie一直不失效。但是xsser.me中的源码中没有发现如何实现定时任务,只有访问url来保证cookie不失效的方法。

(/scripts/keepsession.php)如下代码:

<?php /**  * keepsession.php keep session执行  * ----------------------------------------------------------------  */ include('../init.php'); $db=DBConnect(); $rows=$db->Dataset("SELECT * FROM ".Tb('keepsession'));

$f=new SaeFetchurl();

foreach($rows as $row){
	if(time()>$row['updateTime']+300){
		$f->setHeader("Cookie",urldecode($row['cookie']));
		$con=$f->fetch($row['url']);
		$db->Execute("UPDATE ".Tb('keepsession')." SET updateTime='".time()."' WHERE id='{$row[id]}'");
	}
}
?>

可以看到,xsser.me使用了新浪提供的API接口SaeFetchurl()来使用cookie访问相应的url,以保证cookie的有效性。但是遗憾的是没有发现调用该脚本的代码。所以只能自力更生了。该API介绍:http://apidoc.sinaapp.com/sae/SaeFetchurl.html。

php定时执行任务的几个方法

PHP的实现决定了它没有Java和.Net这种AppServer的概念, 而http协议是一个无状态的协议, php只能被用户触发, 被调用, 调用后会自动退出内存, 没有常驻内存, 就没有办法准确的定时处理
那么, 如果需要用PHP定时执行某些任务的话, 可以有以下三个方法:

  1. Linux下crontab, windows下计划任务
  2. 找个被频繁调用的网页, 里面加上一个检测代码
  3. set_time_limit(0);
    ignore_user_abort(true);
    死循环

第一个方法是最常见的, 如果php服务器上没有权限去crontab, 也可以找一个自己的机器定期crontab去请求服务器
第二种方法, 论坛上定时清理新帖基本上就是这么实现的, 如果人气不旺的话, 可以考虑去别的火爆点的论坛里面发个图片, 调用自己的php来实现一个trigger就好了。 Discuz!是判断在00:00之后,第一个执行者去执行的。
第三种比较不靠谱, Apache重启了就得重新访问,  fastcgi倒是会好一点。

第一种和第二种在这就不介绍了,只要使用一般不会遇到什么问题。下面讲解第三种,该种方法是纯粹的php代码,但是遇到的问题较多,现详细介绍一下。

关键的两个函数:

 

1、ignore_user_abort(true),这个函数的作用是,无论客户端是否关闭浏览器,下面的代码都将得到执行。

           int ignore_user_abort ([ string $value ] )

设置客户端断开连接时是否中断脚本的执行.PHP以命令行脚本执行时,当脚本终端结束,脚本不会被立即中止,除非设置 valueTRUE,否则脚本输出任意字符时会被中止。返回值:以整型返回之前的设置。PHP 不会检测到用户是否已断开连接,直到尝试向客户机发送信息为止。简单地使用 echo 语句无法确保信息发送,参阅 flush() 函数。

说明:该函数按照字面意思就是“忽略用户中断”,就是使用了该函数的php脚本不管用户有没有退出都会执行下去。配合set_time_limit 和一个死循环就可以实现计划任务,这样在循环体中,去查询是否有任务需要执行!

 

2、set_time_limit(0),这个函数的作用是,取消php文件的执行时间,如果没有这个函数的话,默认php的执行时间是30秒,也就是说30秒后,这个文件就say goodbay了。

 

        void set_time_limit ( int $seconds )

设置允许脚本运行的时间,单位为秒。如果超过了此设置,脚本返回一个致命的错误。默认值为30秒,或者是在php.inimax_execution_time被定义的值,如果此值存在。当此函数被调用时, set_time_limit()会从零开始重新启动超时计数器。换句话说,如果超时默认是30秒,在脚本运行了了25秒时调用 set_time_limit(20),那么,脚本在超时之前可运行总时间为45秒。函数的seconds是最大的执行时间,单位为秒。如果设置为0(零),没有时间方面的限制。

说明:

(1)当php运行于安全模式时,set_time_limit()此功能不能生效。除了关闭安全模式或改变php.ini中的时间限制,没有别的办法。

(2)set_time_limit在windows下可能不起作用。最好是在linux下执行。

(3)如果set_time_limit()有效的话,效果和修改php.inimax_execution_time是一样的。因此,如果可以控制服务器,windows下最好还是直接修改配置文件吧。

示例代码:

<?php
ignore_user_abort(); // run script in background
set_time_limit(0); // run script forever
$interval=60*15; // do every 15 minutes...
do{
// add the script that has to be ran every 15 minutes here
// ...
sleep($interval); // wait 15 minutes
}while(true);
?>

 

转载请注明:jinglingshu的博客 » php实现计划任务研究:ignore_user_abort()/set_time_limit()/sleep()

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址