一、引言
恰逢公司的项目需要用到定时器,在网上搜了许多的资料,虽说PHP本身是无状态的语言,用来做定时器非常的麻烦和耗资源,但是实际应用上还是少不了的。方法有几个:
1,利用计算机系统本身的计划任务
2,利用js前台刷新页面定时访问PHP文件
3,利用PHP死循环长连接
由于1,2两种办法都没办法很好地对定时器进行很好的控制,而本篇主要讲的是可控制的定时器,因此我们来详看第三种方法。
二、思路
思路其实不复杂,利用 while(true)死循环让PHP脚本一直处于执行的状态。但是!要注意的是,PHP本身是有一个机制会中断无响应的脚本的,因此,我们要加上。
ignore_user_abort(false);//当用户关闭页面时服务停止
set_time_limit(0); //设置执行时间,单位是秒。0表示不限制。
set_time_limit(0); //设置执行时间,单位是秒。0表示不限制。
先给出一个基本的范式,其中有个人的测试程序:
<?php ignore_user_abort(); // run script. in background set_time_limit(0); // run script. forever $interval=30; // do every 15 minutes... do{ $fp = fopen('text3.txt','a'); fwrite($fp,'test'); fclose($fp); sleep($interval); // wait 15 minutes }while(true); ?>
首先运行该程序,然后关闭该页面,程序仍然运行中,test会每隔30秒的填补到text3.txt文件。
至此一个简单的定时器算是OK了,但是它是不可控制的,因为程序处于死循环中,是无法接受外界的数据的。
那么我们要实现可控制,怎么办呢?解决办法是有的,这里很多种办法,比如读数据库,读文件,我带来的方法也简单,就是用PHP本身的INCLUDE,这样效率也不会太低,消耗的资源也不会太过于大!
即:在死循环中,加一个 if();,判断的条件,就是 $flag = include '路径/配置文件.php';
而这个 [配置文件.php] 的内容很简单,就一句:<?php return true; ?>
当你需要这个定时器停下来的时候,用文件函数fopen打开这个配置文件,然后替换true为false就可以了,这就是基本的思路!
三、源码例子
<?php ignore_user_abort (); // 即使Client断开(如关掉浏览器),PHP脚本也可以继续执行. set_time_limit ( 0 ); // 执行时间为无限制,php默认的执行时间是30秒,通过set_time_limit(0)可以让程序无限制的执行下去 class money extends admin { public $timer_switch; //定时器-开关-文件 public $timer_h; //定时器-时-文件 public $timer_m; //定时器-分-文件 public $timer_delay; //定时器-间隔时间(秒)-文件 public $timer_value; //利息利率 public function __construct(){ parent::__construct(); $this->db = System::load_sys_class("model"); $this->timer_switch = dirname(__FILE__)."\\timer_switch.php"; $this->timer_h = dirname(__FILE__)."\\timer_h.php"; $this->timer_m = dirname(__FILE__)."\\timer_m.php"; $this->timer_delay = dirname(__FILE__)."\\timer_delay.php"; $this->timer_value = dirname(__FILE__)."\\timer_value.php"; } public function index(){ if(isset($_POST['submit'])){ $this->h($_POST['h']); $this->m($_POST['m']); $this->delay($_POST['delay']); $this->value($_POST['value']); $msg = '【保存成功】'; } $switch = include $this->timer_switch; $h = include $this->timer_h; $m = include $this->timer_m; $delay = include $this->timer_delay; $value = include $this->timer_value; include $this->tpl(ROUTE_M,'money_index'); } public function h($s){ $string = '<?php return "'.$s.'";?>'; write_inc($this->timer_h,$string,true); } public function m($s){ $string = '<?php return "'.$s.'";?>'; write_inc($this->timer_m,$string,true); } public function delay($s){ $string = '<?php return "'.$s.'";?>'; write_inc($this->timer_delay,$string,true); } public function value($s){ $string = '<?php return "'.$s.'";?>'; write_inc($this->timer_value,$string,true); } public function stop(){ $string = '<?php return "stop";?>'; write_inc($this->timer_switch,$string,true); $this->index(); } public function start(){ //必须为暂停状态才可以开始 $timer_switch = include $this->timer_switch; if($timer_switch!='stop'){ $fp = fopen('c:/func.txt','a'); fwrite($fp,date("Y-m-d TH:i:s Z").".结束定时器.\r\n"); fclose($fp); die(); }else{ $fp = fopen('c:/func.txt','a'); fwrite($fp,date("Y-m-d TH:i:s Z").".启动定时器.\r\n"); fclose($fp); $string = '<?php return "start";?>'; write_inc($this->timer_switch,$string,true); } //进入定时器 do{ $timer_switch = include $this->timer_switch; $timer_h = include $this->timer_h; $timer_m = include $this->timer_m; $timer_delay = include $this->timer_delay; $h = intval(date("H")); $m = intval(date("i")); //判断时间 if ($h ==$timer_h && $m == $timer_m) { $fp = fopen('c:/func.txt','a'); fwrite($fp,date("Y-m-d TH:i:s Z").".执行任务了.\r\n"); fclose($fp); $this->calc(); } else { $fp = fopen('c:/func.txt','a'); fwrite($fp,date("Y-m-d TH:i:s Z").".距离执行时间还有".((($timer_h-$h)%24)*60+($timer_m-$m)%60)."分钟.\r\n"); fclose($fp); } //延迟 sleep($timer_delay); //判断是否关闭 if($timer_switch=="stop"){ $fp = fopen('c:/func.txt','a'); fwrite($fp,date("Y-m-d TH:i:s Z").".终止.\r\n"); fclose($fp); $this->ing_off(); die(); } }while(true); } public function calc(){ } } function write_inc($path,$strings,$type=false){ if ($type==false) file_put_contents($path,$strings,FILE_APPEND); else file_put_contents($path,$strings); } ?>
Comments 6 条评论
支持 去我那看看吧 欢迎回访
楼主文章写的真好,加油,欢迎楼主互动我的小站,苏勇博客:www.suyongblog.com
@苏勇 夸奖了~
说得对 顶一个
楼主文章写的真好
不错不错