详解PHP实现定时任务的五种方法


Posted in PHP onJuly 25, 2016

定时运行任务对于一个网站来说,是一个比较重要的任务,比如定时发布文档,定时清理垃圾信息等,现在的网站大多数都是采用PHP动态语言开发的,而对于PHP的实现决定了它没有Java和.Net这种AppServer的概念,而http协议是一个无状态的协议,PHP只能被用户触发,被调用,调用后会自动退出内存,没有常驻内存。

如果非要PHP去实现定时任务, 可以有以下几种解决方案:

一. 简单直接不顾后果型

<?php
ignore_user_abort();//关掉浏览器,PHP脚本也可以继续执行.
set_time_limit(0);// 通过set_time_limit(0)可以让程序无限制的执行下去
ini_set('memory_limit','512M'); // 设置内存限制
$interval=60*30;// 每隔半小时运行
do{
  //ToDo 
  sleep($interval);// 等待5分钟
}
while(true);

缺点: 启动之后,便无法控制, 除非终止 PHP 宿主. 不要采用这样方法, 除非你是黑客.

二. 简单可控型

config.php

<?php
return 1;
?>
cron.php


  
ignore_user_abort();//关掉浏览器,PHP脚本也可以继续执行.
set_time_limit(0);// 通过set_time_limit(0)可以让程序无限制的执行下去
$interval=60*30;// 每隔半小时运行
do{
  $run = include 'config.php';
  if(!$run) die('process abort');
  
  //ToDo
  sleep($interval);// 等待5分钟
}
while(true);

通过 改变config.php 的 return 0 , 来实现停止程序. 一个可行的办法是config.php文件和某个特殊表单交互, 通过HTML页面设置一些变量来进行配置

缺点: 占系统资源, 长时间运行,会有一些意想不到的隐患。比如内存管理方面的问题 .

三. 简单改进型

<?php
$time=15;
$url="http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
/*
  function
*/
sleep($time);
file_get_contents($url);
?>

php脚本sleep 一段时间之后通过访问自身的方式继续执行. 就好像接力赛跑一样..这样就能保证每个PHP脚本执行时间不会太长. 也就不受time_out的限制了.

因为每一次一次循环php文件都是独立执行,所以这种方法,避免了time_out的限制. 但是最好和上边一样 加上控制代码. cofig.php , 以便能够终止进程.

四. 服务器定时任务

Unix平台

如果您使用 Unix 系统,您需要在您的 PHP 脚本的最前面加上一行特殊的代码,使得它能够被执行,这样系统就能知道用什么样的程序要运行该脚本。为 Unix 系统增加的第一行代码不会影响该脚本在 Windows 下的运行,因此您也可以用该方法编写跨平台的脚本程序。

1、在Crontab中使用PHP执行脚本

就像在Crontab中调用普通的shell脚本一样(具体Crontab用法),使用PHP程序来调用PHP脚本,每一小时执行 myscript.php 如下:

# crontab -e
00 * * * * /usr/local/bin/php /home/john/myscript.php

/usr/local/bin/php为PHP程序的路径。

2、在Crontab中使用URL执行脚本

如果你的PHP脚本可以通过URL触发,你可以使用 lynx 或 curl 或 wget 来配置你的Crontab。

下面的例子是使用Lynx文本浏览器访问URL来每小时执行PHP脚本。Lynx文本浏览器默认使用对话方式打开URL。但是,像下面的,我们在lynx命令行中使用-dump选项来把URL的输出转换来标准输出。

00 * * * * lynx -dump http://www.sf.net/myscript.php

下面的例子是使用 CURL 访问URL来每5分执行PHP脚本。Curl默认在标准输出显示输出。使用 "curl -o" 选项,你也可以把脚本的输出转储到临时文件temp.txt。

*/5 * * * * /usr/bin/curl -o temp.txt http://www.sf.net/myscript.php

下面的例子是使用WGET访问URL来每10分执行PHP脚本。-q 选项表示安静模式。"-O temp.txt" 表示输出会发送到临时文件。

*/10 * * * * /usr/bin/wget -q -O temp.txt http://www.sf.net/myscript.php

五. ini_set函数用法详解

PHP ini_set用来设置php.ini的值,在函数执行的时候生效,脚本结束后,设置失效。无需打开php.ini文件,就能修改配置,对于虚拟空间来说,很方便。

函数格式:

string ini_set(string $varname, string $newvalue)

不是所有的参数都可以配置,可以查看手册中的列表。

常见的设置:

@ ini_set('memory_limit', '64M');

menory_limit:设定一个脚本所能够申请到的最大内存字节数,这有利于写的不好的脚本消耗服务器上的可用内存。@符号代表不输出错误。

@ini_set('display_errors', 1);

display_errors:设置错误信息的类别。

@ini_set('session.auto_start', 0);

session.auto_start:是否自动开session处理,设置为1时,程序中不用session_start()来手动开启session也可使用session,

如果参数为0,又没手动开启session,则会报错。

@ini_set('session.cache_expire', 180);

session.cache_expire:指定会话页面在客户端cache中的有限期(分钟)缺省下为180分钟。如果设置了session.cache_limiter=nocache时,此处设置无 效。

@ini_set('session.use_cookies', 1);

session.use_cookies:是否使用cookie在客户端保存会话ID;

@ini_set('session.use_trans_sid', 0);

session.use_trans_sid:是否使用明码在URL中显示SID(会话ID),

默认是禁止的,因为它会给你用户带来安全危险:

    用户可能将包含有效的sid的URL通过email/irc/QQ/MSN等途径告诉其他人。

    包含有效sid的URL可能会保存在公用电脑上。

    用户可能保存带有固定不变的SID的URL在他们的收藏夹或者浏览历史记录里。 基于URL的会话管理总是比基于Cookie的会话管理有更多的风险,所以应当禁用。

PHP定时任务是一个非常有意思的东西,以上就是本文提供的一些解决方案,你也可以通过本文的思路,开发出自己的一种解决方案。希望能帮助到有需要的大家。

PHP 相关文章推荐
PHP 常见郁闷问题答解
Nov 25 PHP
php gzip压缩输出的实现方法
Apr 27 PHP
(PHP实现)只使用++运算实现加法,减法,乘法,除法
Jun 27 PHP
PHP同时连接多个mysql数据库示例代码
Mar 17 PHP
destoon常用的安全设置概述
Jun 21 PHP
PHP错误Warning: Cannot modify header information - headers already sent by解决方法
Sep 27 PHP
PHP实现扎金花游戏之大小比赛的方法
Mar 10 PHP
php根据日期或时间戳获取星座信息和生肖等信息
Oct 20 PHP
PHP匿名函数(闭包函数)详解
Mar 22 PHP
Laravel Eloquent ORM 多条件查询的例子
Oct 10 PHP
laravel高级的Join语法详解以及使用Join多个条件
Oct 16 PHP
PHP中echo与print区别点整理
Mar 09 PHP
Yii2中YiiBase自动加载类、引用文件方法分析(autoload)
Jul 25 #PHP
PHP中session跨子域的三种实现方法
Jul 25 #PHP
Yii2创建控制器(createController)方法详解
Jul 23 #PHP
Yii2主题(Theme)用法详解
Jul 23 #PHP
Yii2创建表单(ActiveForm)方法详解
Jul 23 #PHP
Yii2验证器(Validator)用法分析
Jul 23 #PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
Jul 23 #PHP
You might like
探讨:使用XMLSerialize 序列化与反序列化
2013/06/08 PHP
thinkphp实现数组分页示例
2014/04/13 PHP
PHP接入支付宝接口失效流程详解
2020/11/10 PHP
js 获取服务器控件值的代码
2010/03/05 Javascript
javascript实现面向对象类的功能书写技巧
2010/03/07 Javascript
jquery 面包屑导航 具体实现
2013/06/05 Javascript
extjs表格文本启用选择复制功能具体实现
2013/10/11 Javascript
js与jQuery实现checkbox复选框全选/全不选的方法
2016/01/05 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
2017/02/27 Javascript
微信小程序-横向滑动scroll-view隐藏滚动条
2017/04/20 Javascript
微信小程序后台解密用户数据实例详解
2017/06/28 Javascript
js实现Tab选项卡切换效果
2020/07/17 Javascript
JS实现数组删除指定元素功能示例
2019/06/05 Javascript
jquery.pager.js分页实现详解
2019/07/29 jQuery
layui表单提交到后台自动封装到实体类的方法
2019/09/12 Javascript
Vue.js中provide/inject实现响应式数据更新的方法示例
2019/10/16 Javascript
微信小程序实现同时上传多张图片
2020/02/03 Javascript
PHP网页抓取之抓取百度贴吧邮箱数据代码分享
2016/04/13 Python
pycharm安装和首次使用教程
2018/08/27 Python
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
2019/07/04 Python
Python中zip()函数的解释和可视化(实例详解)
2020/02/16 Python
基于python实现微信好友数据分析(简单)
2020/02/16 Python
HTML5 拖拽批量上传文件的示例代码
2018/03/28 HTML / CSS
SheIn沙特阿拉伯:女装在线
2020/03/23 全球购物
在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern "C"
2014/08/09 面试题
国际贸易专业个人求职信范文分享
2013/12/14 职场文书
教师开学感言
2014/02/14 职场文书
前处理班长职位说明书
2014/03/01 职场文书
副校长个人对照检查材料思想汇报
2014/10/04 职场文书
2014年保卫部工作总结
2014/11/21 职场文书
开场白怎么写
2015/06/01 职场文书
python数据分析之用sklearn预测糖尿病
2021/04/22 Python
如何理解python接口自动化之logging日志模块
2021/06/15 Python
关于使用Redisson订阅数问题
2022/01/18 Redis
《模拟人生4》推出新补丁 “婚礼奇缘”DLC终于得到修复
2022/04/03 其他游戏
浅谈Redis的事件驱动模型
2022/05/30 Redis