PHP实现定时任务的几种处理方法

 更新时间:2016年11月25日 15:39  点击:2039
定时任务执行php程序有两方法,一种是ignore_user_abort来实现定时操作,另一种是利用系统自带的计划任务来操作,如linux中使用Crontab,夼windows机器使用任务计划即可。

下面是网上比较流行的纯PHP实现定时任务的代码,我把他整理完善了下,不过先别急着用,一定要看到最下面。

 代码如下 复制代码

<?php
ignore_user_abort(); // 关掉浏览器,PHP脚本也可以继续执行
set_time_limit(600); // 设置程序的执行时间为600秒
// set_time_limit(0); // 设置程序的执行时间为无限长
$interval = 5; // 每隔5秒运行

do {
    $fp = fopen('sjyhome.txt', 'a'); // 打开 sjyhome.txt
    fwrite($fp, '欢迎来到SJY之家 www.111cn.net'); // 往 sjyhome.txt 写入信息
    fclose($fp); // 关闭 sjyhome.txt
    sleep($interval); // 等待5秒
} while (true);
?>

上面的代码是死循环,即使删除代码文件也无济于事,必须重启WEB才能停止脚本执行。所以我们需要一个执行脚本的开关,我们可以用外部文件引入的方法来实现,在while循环的时候,include开关变量即可。
建立外部引入变量文件 switch.php  内容如下:

 代码如下 复制代码
<?php
return 1;//1执行脚本 0退出执行脚本
?>
改良版的PHP代码
<?php
ignore_user_abort(); // 关掉浏览器,PHP脚本也可以继续执行
set_time_limit(600); // 设置程序的执行时间为600秒
// set_time_limit(0); // 设置程序的执行时间为无限长
$interval = 5; // 每隔5秒运行
$switch = include 'switch.php';
while($switch){
    $fp = fopen('sjyhome.txt', 'a'); // 打开 sjyhome.txt
    fwrite($fp,'欢迎来到SJY之家 www.111cn.net $switch \n'); // 往 sjyhome.txt 写入信息
    fclose($fp); // 关闭 sjyhome.txt
    sleep($interval); // 等待5秒
    $switch = include 'switch.php';
}
exit();
?>

把switch.php文件中的return值改为0,则会自动停止运行。想要再次执行,必须把值改为1,并且打开浏览器再执行一次。
如果$switch值为1,那么即使不设置ignore_user_abort(),关闭浏览器照样无法停止循环,甚至删除代码文件也没用,只能等待超时(默认30秒,set_time_limit自定义执行时间)重启WEB服务。
写在后面的话
本方法纵然可以实现定时功能,可是一旦运行该代码文件,这个进程就一直都在了,对于服务器资源的消耗我没测试过,不过有些空间商或许不会允许长时间占线的进程。
如果自己有VPS或服务器的朋友,建议在服务器中做好计划任务,来执行你网站上的脚本


下面介绍使用Linux中的Crontab来实现的两种方法。

关于crontab的使用,可参考文章:Linux计划任务crontab详解
一、在Crontab中使用PHP执行脚本
就像在Crontab中调用普通的shell脚本一样(具体Crontab用法),使用PHP程序来调用PHP脚本。
每一小时执行myscript.php如下:

 代码如下 复制代码
#crontab -e
00 * * * * /usr/local/bin/php /home/web/3aj.php
/usr/local/bin/php为PHP程序的路径。

二、在Crontab中使用URL执行脚本
如果你的PHP脚本可以通过URL触发,你可以使用lynx或curl或wget来配置你的Crontab。
下面的例子是使用Lynx文本浏览器访问URL来每小时执行PHP脚本。Lynx文本浏览器默认使用对话方式打开URL。但是,像下面的,我们在lynx命令行中使用-dump选项来把URL的输出转换来标准输出。
00 * * * * lynx -dump http://你的网址/script.php
下面的例子是使用CURL访问URL来每5分执行PHP脚本。Curl默认在标准输出显示输出。使用”curl -o”选项,你也可以把脚本的输出转储到临时文件。
*/5 * * * * /usr/bin/curl -o temp.txt http://你的网址/script.php
下面的例子是使用WGET访问URL来每10分执行PHP脚本。-q选项表示安静模式。”-O temp.txt”表示输出会发送到临时文件。
*/10 * * * * /usr/bin/wget -q -O temp.txt http://你的网址/script.php
再介绍一下在Windows下php计划任务的实现

1、新建一个3aj.php,内容如下:

 代码如下 复制代码
<?
$fp = fopen("3aj.txt", "a+");
fwrite($fp, date("Y-m-d H:i:s") . " 成功了!\n");
fclose($fp);
?>

2、新建3aj.bat文件,内容如下:
C:\php\php.exe -q D:\web\3aj.php
3、建立WINDOWS计划任务:
开始–>控制面板–>任务计划–>添加任务计划
浏览文件夹选择上面的3aj.bat文件
设置时间和密码(登陆WINDOWS的保存即可了。
4、右键点击计划任务 -> “运行”即可

下面来看一个利用foreach遍历数组之后再判断数组值是否在字符串中出现过,具体操作代码如下图所示。

例子

 代码如下 复制代码

<?php
function is_exist($str,$key){
 foreach($key as $v){
  if(strpos($str,$v)>-1){
   return true;
  }
 }
 return false;
}
$str = 'abcdefg我们中国';
$key = array('4','5','a');
if(is_exist($str,$key)){
 echo 'YES';
}
else{
 echo 'NO';
}
?>

原理分析

很简单的一个例子我们只要使用foreach遍历数组的值之后再使用strpos($str,$v)>-1来判断数组值是不是在字符串中指定位置了,如果搜索到了就会返回大于或等于0值哦。

PHP CURL与file_get_contents函数都可以获取远程服务器上的文件保存到本地,但在性能上面两者完全不在同一个级别,下面我先来介绍PHP CURL或file_get_contents函数应用例子,然后再简单的给各位介绍一下它们的一些小区别吧。

推荐方法 CURL获取

 代码如下 复制代码

<?php
$c = curl_init();
$url = 'www.111cn.net';
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($c);
curl_close($c);
$pos = strpos($data,'utf-8');
if($pos===false){$data = iconv("gbk","utf-8",$data);}
preg_match("/<title>(.*)<\/title>/i",$data, $title);
echo $title[1];
?>


使用file_get_contents

 代码如下 复制代码

<?php
$content=file_get_contents("http://www.111cn.net/");
$pos = strpos($content,'utf-8');
if($pos===false){$content = iconv("gbk","utf-8",$content);}
$postb=strpos($content,'<title>')+7;
$poste=strpos($content,'</title>');
$length=$poste-$postb;
echo substr($content,$postb,$length);
?>

看看file_get_contents性能

1)fopen/file_get_contents 每次请求远程URL中的数据都会重新做DNS查询,并不对DNS信息进行缓存。但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS 查询。这大大减少了DNS查询的次数。所以CURL的性能比fopen/file_get_contents 好很多。
2)fopen/file_get_contents在请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。(设置header头应该可以)
3)fopen/file_get_contents函数会受到php.ini文件中allow_url_open选项配置的影响。如果该配置关闭了,则该函数也就失效了。而curl不受该配置的影响。
4)curl可以模拟多种请求,例如:POST数据,表单提交等,用户可以按照自己的需求来定制请求。而fopen/file_get_contents只能使用get方式获取数据。
5)fopen/file_get_contents 不能正确下载二进制文件
6)fopen/file_get_contents 不能正确处理ssl请求
7)curl 可以利用多线程
8)使用 file_get_contents 的时候如果 网络出现问题, 很容易堆积一些进程在这里
9)如果是要打一个持续连接,多次请求多个页面。那么file_get_contents就会出问题。取得的内容也可能会不对。所以做一些类似采集工作的时候,肯定就有问题了。对做采集抓取的用curl,如果还有同不相信下面我们再做个测试

curl与file_get_contents性能对比PHP源代码如下:
1829.php

 代码如下 复制代码
<?php
/**
 
* 通过淘宝IP接口获取IP地理位置
 
* @param string $ip
 
* @return: string
 
**/
function getCityCurl($ip)
{
    $url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip;
    $ch = curl_init();
    $timeout = 5;
    curl_setopt ($ch, CURLOPT_URL, $url);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $file_contents = curl_exec($ch);
    curl_close($ch);
 
    $ipinfo=json_decode($file_contents);
    if($ipinfo->code=='1'){
        return false;
    }
    $city = $ipinfo->data->region.$ipinfo->data->city;
    return $city;
}
 
function getCity($ip)
{
    $url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip;
    $ipinfo=json_decode(file_get_contents($url));
    if($ipinfo->code=='1'){
        return false;
    }
    $city = $ipinfo->data->region.$ipinfo->data->city;
    return $city;
}
 
// for file_get_contents
$startTime=explode(' ',microtime());
$startTime=$startTime[0] + $startTime[1];
for($i=1;$i<=10;$i++)
{
   echo getCity("121.207.247.202")."</br>";
}
$endTime = explode(' ',microtime());
$endTime = $endTime[0] + $endTime[1];
$totalTime = $endTime - $startTime;
echo 'file_get_contents:'.number_format($totalTime, 10, '.', "")." seconds</br>";
 
//for curl
$startTime2=explode(' ',microtime());
$startTime2=$startTime2[0] + $startTime2[1];
for($i=1;$i<=10;$i++)
{
   echo getCityCurl('121.207.247.202')."</br>";
}
$endTime2 = explode(' ',microtime());
$endTime2=$endTime2[0] + $endTime2[1];
$totalTime2 = $endTime2 - $startTime2;
echo "curl:".number_format($totalTime2, 10, '.', "")." seconds";
?>

测试访问

file_get_contents速度:4.2404510975 seconds
curl速度:2.8205530643 seconds

curl比file_get_contents速度快了30%左右,最重要的是服务器负载更低.

一个简单好用的Php自用分页函数,有需要使用分页函数又不想手写的朋友可进入参考。
 代码如下 复制代码
/*
 * 前台分页
 *
 * $page_array = array(
 *  'totle'     =>10,    //总数
 *  'dispage'   =>10,    //每页显示条数
 *  'url'       =>'/article/list/',//url地址
 *  'now_page', =>1, //当前所在页数
 * );
 *
* @return   pagenav
*/
function front_page( $page_array ){
 
    //分页判断
    $lastpage = ceil($page_array['total'] / $page_array['dispage']); //最后一页
    $page_array['now_page'] = min( $lastpage , $page_array['now_page'] );//比较当前页数和最后一页
    $prepage = $page_array['now_page'] - 1;//上一页
    $nextpage = ($page_array['now_page'] == $lastpage ? 0 : $page_array['now_page'] + 1 );//下一页
    $firstcount = ($page_array['now_page']-1) * $page_array['dispage'];
    if( $lastpage <= 1) return false;//最后一页小于1,则直接返回
 
    //首页
    if($prepage){
        $page_array[]="<a href='{$page_array['url']}"."1/'>首页</a>";
    }else{
        $page_array[]="<span class=\"nolink\">首页</span>";
    }
    //上一页
    if($prepage) {
        $page_array[]="<a  href='{$page_array['url']}$prepage/'> 上一页 </a> ";
    }else{
        $page_array[]='';
    }
 
    //显示的数字分页条数
    $pagenum=5;
    $offset=2;//偏移两
    $from=$page_array['now_page'] - $offset;//起始
    $to=$page_array['now_page'] + $pagenum-$offset-1;//终止
    if($pagenum>$lastpage){
        $from=1;
        $to=$lastpage;
    }else{
        if($from<1){
            $to=$page_array['now_page'] + 1 - $from;
            $from=1;
            if(($to-$from)<$pagenum && ($to-$from)<$lastpage){
                $to=$pagenum;
            }
        }elseif($to>$lastpage){
            $from=$page_array['now_page'] - $lastpage+$to;
            $to=$lastpage;
            if(($to-$from)<$pagenum && ($to-$from)<$lastpage){
                $from=$lastpage-$pagenum+1;
            }
        }
    }
    for($i=$from;$i<=$to;$i++){
        if($i == $page_array['now_page']){
            $pagenav.="<a href=\"#\" title=\"\">$i</a> ";
        }else{
            $pagenav.="<a href=\"{$page_array['url']}$i/\" title=\"\">$i</a> ";
 
        }
    }
    //数字分页
    $page_array[]= $pagenav;
    //下一页
    if($nextpage){
        $page_array[]="<a href='{$page_array['url']}"."$nextpage/'> 下一页 </a> ";
    }else {
        $page_array[]='';
    }
    //尾页
    if($nextpage){
        $page_array[]="<a href='{$page_array['url']}"."$lastpage/'>尾页</a>";
    }else{
        $page_array[]='<span class="nolink">尾页</span>';
    }
    //记录数
    $page_array[]="<span>每页   ".$page_array['dispage']."  条</span> <span>共  ".$page_array['total']."  条纪录</span>";
    //分页数
    $page_array[]="共  ".$lastpage." 页";
 
    //跳页
    $page_array[] = '<span>跳转到:</span><input size="4" id="pagenu" type="text" onkeydown="javascript:if(event.keyCode==13){var page=(this.value<0)?1:this.value;location=\''.$page_array['url'].'\'+page;}" />
                    <a href="javascript:void(0)" onclick="javascript:var spage=(window.document.getElementById(\'pagenu\').value==\'\')?1:window.document.getElementById(\'pagenu\').value;location=\''.$page_array['url'].'\'+spage;">Go</a>';
    //第一页总数
    $firstcount=$firstcount < 1 ? 0 : $firstcount;
    return array('pagenav'=>$page_array,'limit'=>$firstcount,'offset'=> $page_array['dispage'],'allpage'=>$lastpage);
}
PHP定时执行程序脚本我写过不少文章不过都被那些大站采集过去了,结果百度算法有问题大站有排名我的没有,下面我今天再来给各位整理一些不错的定时执行程序的php代码

今天分享一个超简单直接的PHP定时执行的小代码,关掉浏览器,PHP脚本也能后继续执行!

用web浏览器定时刷新今天想到用sleep函数来实现php 自动定时执行。只要php能运行即可。

由于代码少,这里给个例子直接解释:

 代码如下 复制代码

<?php

ignore_user_abort();//关掉浏览器,PHP脚本也可以继续执行

set_time_limit(20);//程序超时时间,单位秒;通过set_time_limit(0)可以让程序无限制的执行下去;当用了set_time_limit()函数设置运行时间,sleep()函数在执行程序时的持续时间将会被忽略掉

$interval=5;//每隔多少秒运行,单位:秒

do{
//这里是你要执行的代码
$i = 1;
$num_file = "number.txt";
$fp = fopen($num_file,"r");
$buf = fread($fp,filesize($num_file));
fclose($fp);

$number = file_get_contents($num_file);
$number = $number+$i;
$fp = fopen($num_file,"w");
fwrite($fp,$number);
fclose($fp);
echo $number;

//等待执行的时间
sleep($interval);
}
while(true);

?>

上面方法如果关了浏览器好像就不行了,我们可以尝试使用平台的计划任务来处理

1、windows 的计划任务
2、linux的脚本程序

代码如下:
PHP

 代码如下 复制代码

<?php
 if($_GET['ac']=='stop')
 exit();
 sleep(5);
 $name=time();
 $fp=fopen("$name.txt",'w');
 fwrite($fp,time());
 fclose($fp);
 $fp = fsockopen('localhost', 80, $errno, $errmsg);
 fputs($fp, "GET /test/time.php\r\n\r\n");
 fclose($fp);
 ?>

在浏览器里执行一下http://localhost/test/time.php
则会在test 文件夹下每隔5秒自动创建一个以当前时间戳命名的txt文件,并写入当前时间戳
可以发现即使关闭了浏览器。这个脚本还是会每5秒执行一次。
这样就达到了定时执行的目的。
如果是要按时间点执行,比如每天 1点钟的时候执行。
那么也只需要小小修改一下也能够实现。
当然这只是一种解决思路,至于实际应用,还要再探索一番

还有一种实现方法:利用死循环,原理差不多

PHP

 代码如下 复制代码

<?php
ignore_user_abort(true);
set_time_limit(0);while(1){
$fp  = fopen('time_task.txt',"a+");
$str = date("Y-m-d h:i:s")."n";
fwrite($fp,$str);
fclose($fp);
sleep(1800);    //半小时执行一次
if(!file_exists('1.txt'))
     exit();          //在目录下建立一个文件1.txt,如果文件存在一直执行,如果文件不存在则退出
}
?>

补充这样也可以

<?php
ignore_user_abort();//关闭浏览器后,继续执行php代码
set_time_limit(0);//程序执行时间无限制
$sleep_time = 5;//多长时间执行一次
$switch = include 'switch.php';
while($switch){
$switch = include 'switch.php';
$fp = fopen('test.txt','a+');
fwrite($fp,"这是一个php博客:phpddt.com $switch \n");
fclose($fp);
sleep($sleep_time);
}
exit();

?>

[!--infotagslink--]

相关文章

  • php 中file_get_contents超时问题的解决方法

    file_get_contents超时我知道最多的原因就是你机器访问远程机器过慢,导致php脚本超时了,但也有其它很多原因,下面我来总结file_get_contents超时问题的解决方法总结。...2016-11-25
  • php语言实现redis的客户端

    php语言实现redis的客户端与服务端有一些区别了因为前面介绍过服务端了这里我们来介绍客户端吧,希望文章对各位有帮助。 为了更好的了解redis协议,我们用php来实现...2016-11-25
  • HTTP 408错误是什么 HTTP 408错误解决方法

    相信很多站长都遇到过这样一个问题,访问页面时出现408错误,下面一聚教程网将为大家介绍408错误出现的原因以及408错误的解决办法。 HTTP 408错误出现原因: HTT...2017-01-22
  • jQuery+jRange实现滑动选取数值范围特效

    有时我们在页面上需要选择数值范围,如购物时选取价格区间,购买主机时自主选取CPU,内存大小配置等,使用直观的滑块条直接选取想要的数值大小即可,无需手动输入数值,操作简单又方便。HTML首先载入jQuery库文件以及jRange相关...2015-03-15
  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • php抓取网站图片并保存的实现方法

    php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
  • ps把文字背景变透明的操作方法

    ps软件是现在非常受大家喜欢的一款软件,有着非常不错的使用功能。这次文章就给大家介绍下ps把文字背景变透明的操作方法,喜欢的一起来看看。 1、使用Photoshop软件...2017-07-06
  • intellij idea快速查看当前类中的所有方法(推荐)

    这篇文章主要介绍了intellij idea快速查看当前类中的所有方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-09-02
  • JS实现的简洁纵向滑动菜单(滑动门)效果

    本文实例讲述了JS实现的简洁纵向滑动菜单(滑动门)效果。分享给大家供大家参考,具体如下:这是一款纵向布局的CSS+JavaScript滑动门代码,相当简洁的手法来实现,如果对颜色不满意,你可以试着自己修改CSS代码,这个滑动门将每一...2015-10-21
  • Mysql select语句设置默认值的方法

    1.在没有设置默认值的情况下: 复制代码 代码如下:SELECT userinfo.id, user_name, role, adm_regionid, region_name , create_timeFROM userinfoLEFT JOIN region ON userinfo.adm_regionid = region.id 结果:...2014-05-31
  • js导出table数据到excel即导出为EXCEL文档的方法

    复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta ht...2013-10-13
  • mysql 批量更新与批量更新多条记录的不同值实现方法

    批量更新mysql更新语句很简单,更新一条数据的某个字段,一般这样写:复制代码 代码如下:UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value';如果更新同一字段为同一个值,mysql也很简单,修改下where即...2013-10-04
  • js基础知识(公有方法、私有方法、特权方法)

    本文涉及的主题虽然很基础,在许多人看来属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题。这里会涉及到对象属性的封装、原型、构造函数、闭包以及立即执行表达式等知识。公有方法 公有方法就是能被外部访问...2015-11-08
  • ps怎么制作倒影 ps设计倒影的方法

    ps软件是一款非常不错的图片处理软件,有着非常不错的使用效果。这次文章要给大家介绍的是ps怎么制作倒影,一起来看看设计倒影的方法。 用ps怎么做倒影最终效果&#819...2017-07-06
  • PHP 验证码不显示只有一个小红叉的解决方法

    最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误; (1)修改步骤如下,原因如下,原因是apache权限没开, (2)点击打开php.int., 搜索extension=ph...2013-10-04
  • c#中分割字符串的几种方法

    单个字符分割 string s="abcdeabcdeabcde"; string[] sArray=s.Split('c'); foreach(string i in sArray) Console.WriteLine(i.ToString()); 输出下面的结果: ab de...2020-06-25
  • 安卓手机wifi打不开修复教程,安卓手机wifi打不开解决方法

    手机wifi打不开?让小编来告诉你如何解决。还不知道的朋友快来看看。 手机wifi是现在生活中最常用的手机功能,但是遇到手机wifi打不开的情况该怎么办呢?如果手机wifi...2016-12-21
  • js控制页面控件隐藏显示的两种方法介绍

    javascript控制页面控件隐藏显示的两种方法,方法的不同之处在于控件隐藏后是否还在页面上占位 方法一: 复制代码 代码如下: document.all["panelsms"].style.visibility="hidden"; document.all["panelsms"].style.visi...2013-10-13
  • 连接MySql速度慢的解决方法(skip-name-resolve)

    最近在Linux服务器上安装MySql5后,本地使用客户端连MySql速度超慢,本地程序连接也超慢。 解决方法:在配置文件my.cnf的[mysqld]下加入skip-name-resolve。原因是默认安装的MySql开启了DNS的反向解析。如果禁用的话就不能...2015-10-21
  • C#方法的总结详解

    本篇文章是对C#方法进行了详细的总结与介绍,需要的朋友参考下...2020-06-25