zoukankan      html  css  js  c++  java
  • php实现定时计划任务

    <?php
    // 这个函数的意思是 无论浏览器是否运行,这段代码仍然执行
    // 在一个php文档的开头直接来一句:

    // ignore_user_abort(true);
    // 这时,通过url访问这个php的时候,即使用户把浏览器关掉(断开连接),php也会在服务器上继续执行。利用这个特性,我们可以实现非常牛的功能,也就是通过它来实现定时任务的激活,激活之后就随便它自己怎么办了,实际上就有点类似于后台任务。

    // 而sleep(n)则是指当程序执行到这里时,暂时不往下执行,而是休息n秒钟。如果你访问这个php,就会发现页面起码要加载n秒钟。实际上,这种长时间等待的行为是比较消耗资源的,不能大量使用。

    // 那么定时任务到底怎么实现呢?使用下面的代码即可实现:
    ignore_user_abort(true);
    set_time_limit(0);
    date_default_timezone_set('PRC'); // 切换到中国的时间

    $run_time = strtotime('+1 day'); // 定时任务第一次执行的时间是明天的这个时候
    $interval = 3600*12; // 每12个小时执行一次

    if(!file_exists(dirname(__FILE__).'/cron-run')) exit(); // 在目录下存放一个cron-run文件,如果这个文件不存在,说明已经在执行过程中了,该任务就不能再激活,执行第二次,否则这个文件被多次访问的话,服务器就要崩溃掉了

    do {
    if(!file_exists(dirname(__FILE__).'/cron-switch')) break; // 如果不存在cron-switch这个文件,就停止执行,这是一个开关的作用
    $gmt_time = microtime(true); // 当前的运行时间,精确到0.0001秒
    $loop = isset($loop) && $loop ? $loop : $run_time - $gmt_time; // 这里处理是为了确定还要等多久才开始第一次执行任务,$loop就是要等多久才执行的时间间隔
    $loop = $loop > 0 ? $loop : 0;
    if(!$loop) break; // 如果循环的间隔为零,则停止
    sleep($loop);
    // ...
    // 执行某些代码
    // ...
    @unlink(dirname(__FILE__).'/cron-run'); // 这里就是通过删除cron-run来告诉程序,这个定时任务已经在执行过程中,不能再执行一个新的同样的任务
    $loop = $interval;
    } while(true);

    // 通过执行上面这段php代码,即可实现定时任务,直到你删除cron-switch文件,这个任务才会停止。

    // 但是有一个问题,也就是如果用户直接访问这个php,实际上没有任何作用,页面也会停在这个地方,一直处于加载状态,有没有一种办法可以消除这种影响呢?fsockopen帮我们解决了这个问题。

    // fsockopen可以实现在请求访问某个文件时,不必获得返回结果就继续往下执行程序,这是和curl通常用法不一样的地方,我们在使用curl访问网页时,一定要等curl加载完网页后,才会执行curl后面的代码,虽然实际上curl也可以实现“非阻塞式”的请求,但是比fsockopen复杂的多,所以我们优先选择fsockopen,fsockopen可以在规定的时间内,比如1秒钟以内,完成对访问路径发出请求,完成之后就不管这个路径是否返回内容了,它的任务就到这里结束,可以继续往下执行程序了。利用这个特性,我们在正常的程序流中加入fsockopen,对上面我们创建的这个定时任务php的地址发出请求,即可让定时任务在后台执行。如果上面这个php的url地址是www.yourdomain.com/script.php,那么我们在编程中,可以这样:
    // function _sock($url) {
    // $host = parse_url($url,PHP_URL_HOST);
    // $port = parse_url($url,PHP_URL_PORT);
    // $port = $port ? $port : 80;
    // $scheme = parse_url($url,PHP_URL_SCHEME);
    // $path = parse_url($url,PHP_URL_PATH);
    // $query = parse_url($url,PHP_URL_QUERY);
    // if($query) $path .= '?'.$query;
    // if($scheme == 'https') {
    // $host = 'ssl://'.$host;
    // }

    // $fp = fsockopen($host,$port,$error_code,$error_msg,1);
    // if(!$fp) {
    // return array('error_code' => $error_code,'error_msg' => $error_msg);
    // }
    // else {
    // stream_set_blocking($fp,true);//开启了手册上说的非阻塞模式
    // stream_set_timeout($fp,1);//设置超时
    // $header = "GET $path HTTP/1.1 ";
    // $header.="Host: $host ";
    // $header.="Connection: close ";//长连接关闭
    // fwrite($fp, $header);
    // usleep(1000); // 这一句也是关键,如果没有这延时,可能在nginx服务器上就无法执行成功
    // fclose($fp);
    // return array('error_code' => 0);
    // }
    // }

    // _sock('www.yourdomain.com/script.php');

  • 相关阅读:
    Laravel Providers——服务提供者的注册与启动源码解析
    基于visual Studio2013解决算法导论之054图的邻接矩阵表示
    基于visual Studio2013解决算法导论之053图的邻接表表示
    基于visual Studio2013解决算法导论之052深度优先
    基于visual Studio2013解决算法导论之051区间树
    基于visual Studio2013解决算法导论之050强连通分支
    基于visual Studio2013解决算法导论之049活动选择问题
    基于visual Studio2013解决算法导论之048红黑树
    基于visual Studio2013解决算法导论之047赫夫曼编码
    基于visual Studio2013解决算法导论之046广度优先搜索
  • 原文地址:https://www.cnblogs.com/luyu521/p/8214434.html
Copyright © 2011-2022 走看看