PHP实现执行定时任务的几种思路详解

2020-06-05 19:59

PHP本身没有计时功能。PHP的定时任务功能只能通过结合其他工具来实现,比如WordPress的内置wp-cron函数,它非常强大。在本文中,我们将深入分析几个常见的php计时任务。

工具/原材料计算机php及其环境使用CronTab定期在Linux服务器上执行php1让我们从在相对复杂的服务器上执行php开始。如果服务器上安装了php,不管是否安装了诸如nginx或Apache之类的服务器环境软件,都可以执行php文件。在Linux中,使用命令行和CronTab来调度任务是最好的选择,也是最有效的选择。

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

crontab -e

之后,一个文件将以非编辑状态打开,这是虚拟仪器的编辑界面。通过点击键盘上的I并进入编辑模式,可以编辑内容。该文件中的每一行都是定时任务。如果我们创建一个新的行,我们将创建一个新的定时任务(当然,这意味着该行是以某种格式编写的)。让我们举个例子,添加一个新行,如下所示:

00 * * * * lynx-dump http://www.domain.com/script.php

这是什么意思?事实上,上述内容由两部分组成,第一部分是时间,第二部分是操作内容。例如,上面的那个,

00 * * * *

这意味着当当前时间的分钟数为00时,将执行计划的任务。时间部分由5个时间参数组成,即:

小时、天、月、周

第一列表示每分钟1-59分钟或*/1,和/n表示每n分钟,例如*/8表示每8分钟。下面也是一个类比。第二列表示小时1-23 (0表示0点),第三列表示日期1-31,第四列表示月份1-12。第五列表示第0-6周(0表示星期日)

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

Lynx -dump http://域名/文件. php

这意味着通过lynx访问该网址。我们主要使用lynx、curl和wget来实现对正在使用的url的远程访问,如果我们想提高效率,最好的选择是用php直接执行本地php文件,例如:

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

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

我们已经添加了一些必要的计时任务。单击键盘上的Esc键并输入“:wq”以保存设置的计时任务。您还可以在屏幕上看到创建新计时任务的提示。接下来是写你的script.php。

这里将不介绍更多的CronTab用法。如果您想更灵活地使用这个定时任务功能,您应该自己了解关于crontab的更多信息。

终端服务器使用bat定期执行PHP 1。在Windows和linux上有一个类似的cmd和bat文件。bat文件类似于shell文件。执行这个bat文件相当于按顺序执行命令(当然,编程可以通过逻辑实现)。因此,我们可以使用bat命令文件在Windows服务器上实现PHP计时任务。事实上,在windows上任务的时间安排和在linux上是一样的,但是方法和途径是不同的。好了,开始吧。

首先,在你认为合适的地方创建一个cron.bat文件,然后用一个文本编辑器打开它(记事本很好),并在其中写下这样的内容:

D:\网站\测试. php

这句话的意思是,使用php.exe来执行test.php的php文件,就像上面的contab一样,绕过了服务器环境,具有更高的执行效率。写完后,单击保存关闭编辑器。

下一步是设置一个定时任务来运行cron.bat打开一个接一个:“开始->控制面板->任务计划->添加任务计划”,在打开的界面中设置定时任务的时间和密码,通过选择将cron.bat装入其中。当然,这样的计时任务已经建立。右键单击计时任务并运行它。计时任务将开始执行。到时候,cron.bat将运行处理,cron.bat将再次执行php。

Php定时任务1在非自有服务器(虚拟主机)上实现如果网站管理员没有自己的服务器,但租用了虚拟主机,他就不能进入服务器系统执行上述操作。此时应该如何执行php计时任务?事实上,有很多方法。

使用忽略用户中止(真)和睡眠死循环

在php文档的开头,简单地说:

忽略用户中止(true);

此时,当通过url访问这个php时,即使用户关闭浏览器(断开连接),php也会继续在服务器上执行。有了这个特性,我们可以实现一个非常好的功能,即通过它激活一个预定的任务。激活后,我们可以做任何它想做的事情,这实际上有点类似于背景任务。

sleep(n)表示当程序在这里执行时,它不会暂时停止执行,而是会休息n秒。如果你访问这个php,你会发现这个页面至少需要n秒钟来加载。事实上,这种长时间的等待行为相对消耗资源,不能大量使用。

那么计时任务是如何实现的呢?这可以使用以下代码来完成:

& lt?php

忽略用户中止(true);

设置时间限制(0);

日期_默认_时区_设置(& # 39;中国& # 39;);//切换到中国的时间到了

$ run _ time = str time(& # 39;+1天& # 39;);//计时任务将在明天的这个时候第一次执行。

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

如果(!file_exists(dirname(__FILE__)。& # 39;/cron-run & # 39;))退出();//在目录中存储一个克隆运行文件。如果文件不存在,任务将无法再次激活并再次执行。否则,如果文件被多次访问,服务器将崩溃。

做{

如果(!file_exists(dirname(__FILE__)。& # 39;/cron-switch & # 39;))中断;//如果cron-switch文件不存在,将停止执行。这是开关的功能。

$gmt_time = microtime(真);//当前运行时间,精确到0.0001秒

$loop = isset($loop)和。& amp$loop?$循环:$ run _ time-$ GMT _ time;//这里的处理是确定在开始任务的第一次执行之前要等待多长时间。$loop是执行任务之前等待的时间间隔。

$loop = $loop >。0?$循环:0;

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

睡眠(循环);

//...

//执行一些代码

//...

@unlink(dirname(__FILE__)。& # 39;/cron-run & # 39;);//这是通过删除cron-run来告诉程序,此计划任务已经在执行过程中,不能执行新的相同任务。

$ loop = $ interval

}同时(真);

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

然而,有一个问题,即如果用户直接访问这个php,它实际上没有任何效果,页面将在这个地方停止并保持加载。有没有办法消除这种影响?Fsockopen帮助我们解决了这个问题。

当请求访问某个文件时,Fsockopen可以继续执行程序而不获得返回结果,这与curl的常见用法不同。当我们使用curl访问网页时,我们必须等到curl加载了网页之后,再执行curl后面的代码。虽然curl实际上可以实现“非阻塞”请求,但它比fsockopen复杂得多。因此,我们优先考虑fsockopen。fsockopen可以在指定的时间内(例如1秒钟内)完成对访问路径的请求。请求完成后,不管路径是否返回内容,它的任务在此结束,程序可以继续执行。使用这个特性,我们将fsockopen添加到正常的程序流中,并请求我们在上面创建的定时任务php的地址,以便定时任务可以在后台执行。如果上面php的url地址是www.yourdomain.com/script.php,,那么我们可以在编程中这样做:

//...//普通php执行程序//..//远程请求(不获取内容)功能,可在下面重复使用

//...

//普通php执行程序

//..

//远程请求(不获取内容)功能可以重复使用,如下所示

function _sock($url) {

$host =解析_url(网址;

$端口=解析_url(网址;

$port = $port?$ port:80;

$scheme =解析_url(网址;

$path =解析_url($url,PHP _ URL _ PATH);

$query =解析_url($url,PHP _ URL _ QUERY);

if($query) $path。= & # 39;?& # 39;。$ query

if($ scheme = = & # 39;https & # 39){

$ host = & # 39ssl://'。。$ host

}

$fp = fsockopen($host,$port,$error_code,$error_msg,1);

如果(!$fp) {

返回数组(& # 39;错误代码& # 39;=>。$error_code,& # 39;错误消息& # 39;=>。$ error _ msg);

}

否则{

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

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

$ header = & quot获取$路径\r\n;

$header。= & quot主机:$主机\r\n;

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

fwrite($fp,$ header);

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

f close(FP );

返回数组(& # 39;错误代码& # 39;=>。0);

}

}

_ sock(& # 39;Www.domain.com/com/script.php');

//...

//继续执行其他操作

//..

将此代码添加到计划任务提交结果程序中,在设置时间后提交,然后执行上述代码,计划任务可以被激活,并且提交的用户在页面上没有拥塞感。

2使用用户的访问行为来执行一些延迟的任务

-

然而,使用睡眠来完成定时任务是一个非常低效的方案。我们希望不要用这种方法来执行,这样我们可以解决效率问题。我们使用用户访问行为来执行任务。用户对网站的访问实际上是一个非常丰富的行为资源,包括搜索引擎蜘蛛对网站的访问,可以被归类为这种类型。当用户访问网站时,会在内部添加一个操作,以检查任务列表中是否有尚未执行的任务,如果有,则执行该任务。对于使用上述fsockopen的用户来说,他们甚至感觉不到他们的访问做出了这样的贡献。然而,这种访问的缺点是访问非常不规则。例如,您想在凌晨2: 00执行某项任务,但是这个时间段非常不吉利。在早上6: 00之前,没有用户或任何行为到达您的网站进行新的访问。这将导致您最初计划在2点钟执行的任务在6点钟执行。

这涉及到计划任务列表,这意味着您需要一个列表来记录所有任务的时间和要执行的内容。通常,许多系统使用数据库来记录这些任务列表,例如wordpress。简而言之,如果你想管理一个以上的计划任务,不可能在上面放置一个php。你必须想办法建立一个日程表。由于其中的逻辑相当复杂,我们将不再详细阐述。我们只会停留在思考的层面。

3.借用跳板完成第三方预定任务

-

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

4回收包括包含文件(待验证)

-

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

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

//...

//执行一些程序

//...

睡眠(循环);//这个$循环位于include(& # 39;do.php & # 39);以前的任务

包括(dirname(__FILE__)。& # 39;/do . PHP & # 39;);

事实上,这种方法类似于while的思维。睡眠也被利用了,这是低效的。

Php计时任务是一件非常有趣的事情。虽然说实话,用系统的php.exe直接执行php文件更有效,但是对于许多普通的网站管理员来说,虚拟主机不能直接执行PHP中的本地程序。

目标

联系我们

天津市西青区中北镇云锦世家南门55号
4007181001
30998@qq.com

庆典活动

商务会议

企业年会

展会展览