php计划任务定时执行,php指定时间执行某任务

  php计划任务定时执行,php指定时间执行某任务

  在Linux服务器上用CronTab定期执行php。

  让我们从执行php的相对复杂的服务器开始。服务器上安装了php,无论是否安装了nginx或Apache等服务器环境软件,都可以执行php文件。在Linux中,使用命令行和CronTab来调度任务是一个极好的选择,也是最高效的选择。

  首先,进入命令行模式。Linux作为服务器,一般默认进入命令行模式。当然,我们的管理服务器也通过putty等工具远程连接到服务器。为了方便起见,我们以root用户身份登录。在命令行中,键入:

  可以使用

  之后会打开一个文件,处于非编辑状态,是vi的编辑界面。点击键盘上的I,进入编辑模式,就可以编辑内容了。该文件中的每一行都是一个定时任务。当我们创建一个新的行时,我们创建了一个新的定时任务(当然,这意味着在这一行中以某种格式书写)。现在我们举个例子,加一行,内容如下:

  00 * * * * lynx-dump https://www.yourdomain.com/script.php

  这是什么意思?实际上,上面这条线由两部分组成,第一部分是时间,第二部分是操作内容。举个例子,上面这个,

  00 * * * *

  即,当当前时间的分钟是00时,执行计划任务。时间部分由五个时间参数组成,即:

  时间、日期、月份和星期

  第一列表示1 ~ 59分钟每分钟用*/1表示,/n表示每n分钟。例如,*/8表示每8分钟一次,以此类推。

  第二列表示1 ~ 23小时(0表示0点)。

  第三列表示从1到31的日期。

  第四列表示从1到12的月份。

  第5列标识号是第0 ~ 6周(0表示星期日)。

  整句的后半部分是操作的具体内容。

  lynx-dump https://www.yourdomain.com/script.php

  意思是通过lynx访问这个url。我们主要使用lynx、curl和wget来远程访问url,如果要提高效率,直接使用php来执行本地php文件是最好的选择,比如:

  00 */2 * * */usr/local/bin/PHP/home/www/script . PHP

  这条语句可以通过linux的内部php环境每2小时0分钟执行一次script.php。注意不是通过url访问,而是通过服务器环境,而是直接。因为绕过了服务器环境,效率当然高很多。

  好了,您已经添加了一些必需的计划任务。点击键盘上的Esc键,输入“:wq”进入,设置的定时任务被保存,屏幕上可以看到创建新定时任务的提示。下一步是写你的script.php。

  CronTab的更多用法这里就不介绍了。如果想更灵活地使用这个定时任务功能,那就要自己去了解crontab。

  在Windows server上使用bat定期执行php。

  windows和linux上有类似的cmd和bat文件,bat文件类似于shell文件。执行这个bat文件相当于依次执行里面的命令(当然编程也可以用逻辑来实现)。因此,我们可以使用bat命令文件在windows服务器上实现PHP调度任务。其实windows上的任务计时原理和linux上的是一样的,只是方法和途径不同。好了,开始了。

  首先,在您认为合适的位置创建一个cron.bat文件,然后用文本编辑器(记事本也可以)打开它,并在其中编写如下内容:

  这句话的意思是,用php.exe执行php文件test.php,和上面的contab一样,绕过了服务器环境,执行效率比较高。写完后,点击保存关闭编辑器。

  接下来就是设置一个调度任务运行cron.bat依次打开“开始-控制面板-任务计划-添加任务计划”,在打开的界面中设置调度任务的时间和密码,选择挂载cron.bat。好了,这样一个定时任务就成立了。右键点击定时任务并运行,定时任务将开始执行。到时候会运行cron.bat进行处理,cron.bat会再次执行php。

  在非自有服务器(虚拟主机)上实现php调度任务

  如果站长租用虚拟主机,而不是自己的服务器,就无法访问服务器系统进行上述操作。这时候应该如何执行php计时任务?其实方法很多。

  使用ignore_user_abort(true)并休眠无限循环。

  在一个php文档的开头,只需说:

  ignore_user_abort(真);

  此时,当通过url访问这个php时,即使用户关闭(断开)浏览器,php也会继续在服务器上执行。有了这个功能,我们就可以实现一个非常牛逼的功能,就是可以通过它来激活预定的任务,激活之后就可以为所欲为了,其实有点类似于后台任务。

  而sleep(n)是指程序在这里执行的时候,暂时不会执行下来,而是休息n秒。如果你访问这个php,你会发现页面加载至少需要N秒。实际上,这种长时间等待的行为消耗的资源更多,无法大量使用。

  那么如何实现定时任务呢?使用以下代码来实现它:

  date_default_timezone_set(PRC )。//是时候切换到中国了

  $run_time=strtotime( 1天);//第一次执行预定任务是明天的这个时候。

  $ interval=3600 * 12//每12小时执行一次

  如果(!file_exists(目录名(__FILE__)。/cron-run ))exit();//在目录中存储一个cron-run文件。如果这个文件不存在,意味着它已经在执行过程中。该任务不能被再次激活和第二次执行。否则,如果该文件被多次访问,服务器将会崩溃。

  如果(!file_exists(目录名(__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;

  如果(!$ loop)break;//如果循环的间隔为零,则停止

  sleep($ loop);

  //.

  //执行一些代码

  //.

  @unlink(目录名(__文件_ _)。/cron-run’);//这里是通过删除cron-run告诉程序,这个调度的任务已经在执行过程中了,不能再执行新的相同的任务。

  $ loop=$ interval

  } while(真);

  通过执行上面的php代码,可以实现定时任务,直到删除cron-switch文件才会停止。

  但是有一个问题,就是如果用户直接访问这个php,其实并没有什么影响,页面会停在这个地方,一直加载。有办法消除这种影响吗?Fsockopen帮助我们解决了这个问题。

  Fsockopen可以实现当一个文件被请求访问时,它可以继续执行程序,而不会得到返回结果,这与curl的通常用法不同。当我们使用curl访问网页时,必须等待curl加载网页后,才能执行curl后面的代码。虽然curl实际上可以实现“无阻塞”的要求,但是比fsockopen复杂得多。所以我们优先考虑fsockopen,它可以在指定的时间内,比如1秒以内,完成对访问路径的请求。完成后,路径是否返回内容并不重要。它的任务到这里就结束了,它可以继续执行程序。利用这个特性,我们在正常的程序流程中加入fsockopen,向上面提到的定时任务php的地址发出请求,这样定时任务就可以在后台执行了。如果上述php的url地址是www.yourdomain.com/script.php,那么我们可以在编程中这样做:

  stream_set_blocking($fp,true);//开启手册中提到的非阻塞模式。

  stream_set_timeout($fp,1);//设置超时

  $ header= GET $ path HTTP/1.1 r n ;

  $header。= Host:$ Host r n ;

  $header。=连接:关闭 r n r n ;//长连接关闭

  fwrite($fp,$ header);

  us LEEP(1000);//这句话也是关键。如果没有这个延迟,它可能无法在nginx服务器上成功执行。

  fclose($ FP);

  返回数组( error _ code =0);

  _ sock( www . your domain . com/script . PHP );

  //.

  //继续执行其他动作

  //.

  将此代码添加到计划任务提交结果程序中。设置好时间后,提交然后执行上面的代码激活预定的任务,对于提交的用户来说,页面没有出现拥堵的情况。

  借用用户的访问行为来执行一些延期任务

  然而,利用睡眠来实现预定任务是低效的。我们希望不要用这种方法,这样效率问题就可以解决了。我们借用用户访问行为来执行任务。用户对网站的访问,其实是一种非常丰富的行为资源,包括搜索引擎蜘蛛对网站的访问,都可以算作这种类型。当用户访问网站时,在内部添加一个动作,检查任务列表中是否有未执行的任务,如果有,则执行该任务。对于用户来说,使用上面提到的fsockopen,他们甚至感觉不到自己的访问做出了这样的贡献。但这种拜访的缺点是很不规律。比如你想在凌晨2点执行某项任务,但是这个时间段非常不吉利。没有用户或者任何行为到达你的网站,早上6点之前没有新的访问。这就导致了你原本计划2点执行的任务,直到6点才执行。

  这涉及到一个预定的任务列表,也就是说你需要有一个列表来记录所有任务的时间和内容。一般来说,很多系统使用数据库来记录这些任务列表,比如wordpress。我使用文件读写特性来提供一个托管在github上的开源项目php-cron。你可以看看。总之,如果要管理多个调度的任务,上面单个php是无法合理布局的,必须想办法建立一个调度列表。因为这里的逻辑比较复杂,就不详细阐述了。我们只停留在思考的层面。

  借用第三方预定任务的跳板

  有趣的是,一些服务提供商提供各种类型的定时任务。比如阿里云的ACE提供了单独的定时任务,你可以在自己的应用下填写某个uri。百度云BCE提供了服务器监控功能,每天会按照一定的时间规则访问应用下的固定uri。类似的第三方平台上也有很多可调度的任务。您可以使用这些第三方计划任务作为跳板,为您的网站计划任务提供服务。比如你可以在阿里云ACE上设置一个每天凌晨2: 00的定时任务,要执行的uri是/cron.php,然后你创建一个cron.php,它使用fsockopen访问你真正要执行一些任务的网站的url,比如上面的www.yourdomain.com/script.php,你也可以访问cron.php的多个URL。然后把cron.php上传到你的ACE,让ACE的预定任务访问/cron.php,然后让cron.php远程请求目标网站的预定任务脚本。

  包含循环包含的文件(待验证)

  Php面向过程的特性使得它的程序自顶向下执行。使用这个特性,当我们使用一个包含的文件时,我们将执行引入的文件。在我们知道包含文件中的程序已经被执行后,我们将继续执行它。如果我们创建一个循环,然后用sleep连续包含某个文件,从而循环执行某个程序,就可以达到规则执行的目的。我们更进一步,不是用while(true)来实现循环,而是用包含文件本身来包含自身来实现循环。例如,我们创建一个包含以下内容的do.php:

  如果(.)exit();//通过某个开关关闭执行

  //.

  //执行一些程序

  //.

  sleep($ loop);//这个$循环在include( do . PHP );以前的任务

  包含(目录名(__文件_ _)。/do . PHP’);

  其实这个方法和while的想法差不多。利用睡眠也是低效的。

php计划任务定时执行,php指定时间执行某任务