Crontab Linux/UNIX 系统上最常用 的计划任务 理工具 PHP 开发者在实际项目中
会经常使用到该工具。不过受限于实际的项目部署应用环境, Crontab 置信息的编辑多
由专门的服务器维护人员操作,项目使用者想要自行添加和编辑,流程较为烦琐。
本章将会基于内容管理框架,开发 个可视化的 Crontab 计划任务管理模块,极大地
方便了开发者和用户的使用。
# 1 常见计划任务实现万法
在实际开发中,经常会遇见有计划任务需求的场景,如创建但未支付的订单,或失败
需要退款的商品等,这些都需要定时执行某些操作。类似的场景还有许多。本节主要讲解
常见的几种计划任务的实现方法。
## 1.1 PHP 脚本实现计划任务
因为 PHP 脚本是基于浏览器运行的,在关闭浏览器后程序会自动终止,同时程序执
行的最大时间默认为 秒,所以要让 PHP 脚本实现计划任务,就需要一个或多个脚本,
不依赖浏览器的动作而可以一直执行。下面给出常见方法。
- 脚本执行时间限制:使用 PHP 内置的 set_time_limit()方法可以实现让脚本持续执行。
- 浏览器关闭,程序不终止:使用 PHP 内置的 ignore_user_ abort()方法,可以让脚本在关闭浏览器的情况下可以继续执行。
-
脚本定时执行 为了不让 PHP 提前结束进程,使用语言内置的无限循环结构和
sleep()等待方法可以让脚本定时执行,如 5秒执行1次。
这里给出一个简单的脚本实例,演示 PHP 计划任务的实现过程。新建 task.php 本文
件,实现代码如下:
```php
<?php
ignore_user_abort(); //关闭浏览器 PHP 脚本也可以继续执行
set_time_limit(0); //通过 set me limit (0 )可以让程序无限制地执行下去
$interval = 3 ; //每隔3秒运行
$number = 0; //计数器
//无限循环
do{
($number < 10) {
//执行 次文件写入操作
//定时写入文件
file_put_contents( _DIR_.'/log/log'.date('Ymd_His').'.log',time()) ;
$number =$number+1 ;
sleep($interval); //延时执行
}while(true) ;
```
在上述代码中,实现了循环内的代码每 秒执行 次, 共执行 10 次的计划任务(新
log 文件) 。注意脚本头文件中定义的两个系统方法,代码如下:
```php
ignore_user_abort(); //关闭浏览器 PHP 脚本也可以继续执行
set_time_limit(0); //通过 set me limit (0 )可以让程序无限制地执行下去
```
在浏览器中访问 task .php 脚本,可以发现在 lo 目录下,会自动新增 10 log 文件,
不过使用这种方式,若更新了 PHP 文件内容,需要 重启PHP进程才可以使计划任务
生效。 此外, 若出现程序错误或者内存溢出, PHP 当前运行的进程也会被终止,故使用这
种方式具有极大的不稳定性,维护起来并不方便。
## 1.2 使用系统级别的计划任务工具
既然使用 PHP 脚本实现计划任务,在一些方面不是很理想,那么借助外部的工具就
是更好的选择。无论是windows 还是 Linux 操作系统,都有完 的计划任务解决方案
如在 Windows 10 中, 在控制面板中,就可以直接找到任务计划程序井管理计划任务,使
用起来较为简单,
不过基于 PHP 项目, 一般部署在windows 服务器上的较少,故 PHP 开发者最常用
的还是 Linux系统中的 Crontab 计划任务命令工具 为了方便演示,这里使用 vagrant 工具,
在本地搭建 Ubun 的虚拟机系统,登录成功后 执行以下命令查看 Crontab 帮助信息。
```bash
crontab -h
```
结果如下
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210320040711542.png)
也可以执行以下命令,查看管理员用户( root )有哪些计 任务。
```bash
crontab -l
```
执行结果如下
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210320040803601.png)
其实无论使用哪个计划任务工具,都是为了实现在特定的时间执行某项任务这样的功
# 2.Crontab 入门
Linux 上的 Crontab 计划任务工具 没有可视化的交互界面 配置与使用该工具都需
要在 令行 作, 本节主要讲解 Cron tab 工具的 些入 操作。
## 2.1 Crontab 使用教程
在讲之前之前, 需要先了解 Cron 和 Crontab 的区别。经常使用到的 Crontab 命令
是Cron和 Table 合体的简写 它其实是 Cron 配置文件,也可以 作业列 开发者可
以在 定义不同的时间表达式 实现不同的任务需求。
而 Cron是Linux 系统进程,Cron 搭配 Shell 脚本,就可以执行特定的计划任务。
以ubun 16.04 为例 Cron tab 在系统中多个地方都有配置文件。
- /var/spool/cron/crontabs:该目录下存放的是每个用户的 Crontab ,配置文件的 与用户名一 致。
- /etc/cron.d/: 存放需要执行的 Crontab 文件或脚本。
- /etc/cron.hourly、 /etc/cron.daily 、/etc/cron.weekly 、/etc/cron。monthly:这些目录中的脚本,可以以每小时、每天、每星期和每月为单位执行1次。
常用的命 明如下:
`crontab [- u username)` //省略用户表表示操作当前用户的 Cron tab
- e 编辑任务列表)
- 1 列出任务列表里的命令)
- r 删除任务列表)
Crontab 的命令构成为 时间表达式+操作符+操作命令。时间表达式的构成有分、时、
日、月、周 5种, 操作符有以下几种:
*:取值范围内的所有数字
/:每过多少个数字
-:从x到z
.:散列数字 例如:每分钟执行一次命令 `showtima` 实例如下: `* * * * * showtima`
每天 30 执行某个 PHP 脚本文件 示例如下
```bash
30 23 * * * /usr/bin/php7.0 /var/www/task.php
```
时间表达式的 义非常灵活 不过若不经常使用,极易导致配置 这里 推荐使用
在线的 Crontab 式生成器 ,根据需求进行定制。访问地址为:http://www pppet.net
访问后使用效果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210320042232621.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmd6aGFl,size_16,color_FFFFFF,t_70)
## 2.2 Crontab 实现 PHP 文件定时写入
为了方便演示,这里实现1个每分钟写入文件日期的功能 首先在系统的/var/www
(Ubun 虚拟机环境)目录下,新增 log.php 文件 体代码如下
```php
<?php
file_put_contents(__DIR__.'/run.log',date("Y-m-d H:i:s")."\r\n",FILE_APPEND);
?>
```
此脚本每次执行,都会生成 个带有当前时间信息的文件,以便区分文件是何时创建
随后执行以下命令,给当前用户增加 Cronta 表达式,指定何时执行 log.php 脚本
```bash
crontab -e
```
增加以下内容:
```bash
* * * * * /use/bin/php7.0 /var/www/log.php
```
保存后等待几分钟,发现在/var/www 目录下,自动生成了 run.log 文件,使用 cat
令查看,内 容如下
root@scotchbox:/var/www# cat run.log
2018-01-03 16:01:01
2018-03-03 16:02:01
2018-03-03 16:03:02
根据 Crontab 中配置的时间任务表达式,log.php脚本每隔一分钟都会被执行一次,而
此时修改脚本文件,则不需要重启 PHP 进程,修改的代码如下:
```php
<?php
file_put_contents(__DIR__.'/run.log',"time:".date("Y-m-d H:i:s")."\r\n",FILE_APPEND);
?>
```
经过几分钟的等待,再次查看 ru log 文件,发现己经写入了新的格式内容
2018-01-03 16:01:01
2018-03-03 16:02:01
2018-03-03 16:03:02
2018-01-03 16:04:01
time:2018 01-03 16 : 05 : 01
通过对日志列表细心观 可以发现, Crontab 在执行的时候,默认最小单位为“分”,
并且会从第1 秒(根据配置文件编辑的时间,误差在2秒内)开始执行。开发者还可以通
过使用 sleep 关键字定义在哪1秒执行,修改时间表达式如下:
```bash
* * * * * sleep 20; /use/bin/php7.0 /var/www/log.php
```
sleep 后面的参数 20 指的就是延迟多少秒执行, 等待几分钟后,再次查看 run.log 文件,
发现文件写入的时间发生了变化:
2018-03-03 16:03:02
2018-01-03 16:04:01
time:2018 01-03 16:05:01
time:2018 01-03 16:06:01
time:2018 01-03 16:07:01
time:2018 01-03 16:08: 01
time:2018 01-03 16:10: 21
time:2018 01-03 16:11: 21
# 奇奇怪怪的知识
完成计划任务显示列表管理的开发后,用户就可以 自行定义需要的任务内容了,不过想
要自动运行,还需要 个自动执行任 的脚本,用来理这些任务。其实 步骤如下。
**1. 安装第三方依赖类库**
为了提升开发效率,这里主要安装两个依赖类库,用来解析 Cro tab 表达式和发送
HTTP 请求。在项目的根目录下,安装 mtdowling/cron- expression 的命令如下:
```bash
composer require mtdowling/cron- expression
```
为了更好地获取请求 URL 地址的 HTTP 回值 安装使用 rmccue/requests 的命令
如下
```bash
composer require rmccue/requests
```
**2.开发核心任务脚本**
为了更好地管理代码,在项目 application 目录下,新增 crontab 应用模块,在此模块
下的 controller 目录下,新增 Crontask.php 控制器文件,在此文件内开发任务执行脚本,
其步骤如下。
**(1)新增初始化方法。为了防止误操作 ,此脚本只能在命令行下操作,在 Crontask 控制器文件中,增加以下代码**
```php
/*
*初始化配置列表
@var array
*/
private $_config = [] ;
/*
*初始化方法
*/
public function _initialize(} {
parent::_initialize();
config('app_trace', false) ; //关闭app_trace
//只可以以 cli 方式执行
if(!$this->request- >isCli()){
$this->error("计划任务必须在命令行中执行");
}
//初始化状态
$this->_config=[
'DELETE'=>-1,//己经删除
'DISABLED'=>0,//禁用
'NORMAL'=>1,//正常
'COMPLETED'=>2,//完成
'EXPIRED'=>3,//过期
]
}
```
为了脚本稳定地执行,代码强制关闭了框架自带的 Trace 输出模式,并禁止在非命令
行模式下运行此脚本的任何方法。其代码如下:
```php
config('app_trace', false) ; //关闭app_trace
if(!$this->request- >isCli()){
$this->error("计划任务必须在命令行中执行");
}
```
**(2)实现任务管理核心方法。在控制器新增index()方法,增加以下代码**
```php
/**
*定时任务执行方法
*@return bool
**/
public function index(){
//查询所有的任务列表
$map['status']= ['>', 0];
$crontab_list = Db::name("crontab ")->where ($map)->select();
if(!$crontab_list){
return false;
}
$now_time =time();
foreach($crontab_list as $key =>$cromtab){
$is_execute = false ; //是否执行
$update =[];//需要更新的数据
if($now_time<$cromtab["begin_time"]){
continue;//任务没开始跳过
}
if($cromtab["maximums"] &&$cromtab["executes"]>=$cromtab["maximums"]){
$update["status "]=$this->config["COMPLETED"];// 任务超过最大执行次数 任务完成
}elseif($cromtab["end_time"] >0 && $now_time> $cromtab["end_time"] ){
$update["status "]=$this->config["EXPIRED"];// 任务过期
}else{
//创建计划任务对象并传入时 表达式
$cron = CronExpression::factory($crontab[' schedule']);
if($cron->isDue()){
//允许执行
$is_execute = true ;
//允许执行的时候更新状态
$update["execute_time"]= $now_time;
$update["update_time"]= $now_time;
$update["executes"]=$crontab["executes"]+ 1;
$update["status "]= ($crontab["maximums "]>0 &&$update["executes"]>=$update["maximums "]?$this->config["COMPLETED"]:$this->config["NORMAL"];
)else{
//如果未到 行时间 跳过本任务去判断下一个任务
continue;
}
}
$map= [] ;
$map["id"]= $crontab["id"];
Db::name("crontab")-> where($map)->update($update);
//通过标志位来判断是否满足执行条件(任务是否开始、是否未达到规定次数等)最终决定执行任务还是只更新任务状态
if(!$is_execute){
continue;
}else{
//执行计划任务操作
try{
//判断任务类型
switch($crontab['type']){
//请求 URL
case "url"
if(substr($crontab["content"] ,0,1)=="/"){
//本地url
$request = shell_exec("php".__ROOT_PATH__."index.php".$crontab["content"]."2>&1");
//修改日志
}else{
//远程 URL使用curl请求
//修改日志
}
break;
case "shell"
$request = shell_exec($crontab["content"]."2>&1");
//修改日志
break;
}
}catch(\Execeptionm $e){
////记录异常
}
}
}
```
- 服务器购买到搭建宝塔
- 结构规范
- php基础
- php简介
- php是什么
- PHP 能做什么
- PHP 如何运行
- 如何了解弱语言
- 安装环境
- 安装LNMP
- 宝塔
- phpstudy
- PHP基本语法
- PHP 标记
- 从 HTML 中分离
- 指令分隔符
- 注释
- php 数据类型
- 类型检测
- 四种标量类型
- boolean(布尔型)
- Integer 整型
- Float 浮点型
- String 字符串类型
- 两种复合类型
- array(数组)
- object(对象)
- 两种特殊类型
- resource(资源)
- NULL(无类型)
- 类型转换
- 变量
- 变量定义和命名规范
- 传值和引用
- 预定义变量
- php预定义变量
- $_SERVER详解
- 变量范围
- 全局变量
- 静态变量
- 可变变量
- 常量
- 常量简介
- 常量定义
- 相比变量
- 魔术常量
- 运算符
- 运算符简介
- 算术运算符
- 赋值运算符
- 位运算符
- 比较运算符
- 错误控制运算符
- 执行运算符
- 递增(减)运算符
- 逻辑运算符
- 字符串运算符
- 数组运算符
- 新增操作符
- 控制结构
- 控制简介
- if 语句
- while 语句
- for 语句
- foreach 语句
- break 语句
- continue 语句
- switch 语句
- declare 语句
- return 语句
- include 语句
- PHP 函数
- 函数简介
- 用户自定义函数
- 函数的参数
- 返回值
- 可变函数
- 内部函数
- 匿名函数
- PHP 的类和对象
- PHP 的类和对象简介
- 基本概念
- 对象继承
- 属性
- 类常量
- 自动加载对象
- 构造和析构函数
- 访问控制
- 范围解析操作符(::)
- 静态static
- Static 关键字
- 抽象类
- 接口
- 匿名类
- 面向对象其他特性
- const关键字
- final关键字
- abstract用于定义抽象方法和抽象类。
- self、$this、parent::关键字
- 接口(interface)
- trait关键字
- instanceof关键字
- 魔术方法
- 构造函数和析构函数
- 私有属性的设置获取
- __toString()方法
- __clone()方法
- __call()方法
- 类的自动加载
- 会话控制
- cookie
- PHP 操作 cookie
- 项目实战
- SESSION
- Session 的初步介绍与实验准备
- PHP 操作 session
- 项目实战2
- http
- 特点
- 工作过程
- request
- response
- HTTP状态码
- URL
- GET和POST的区别
- HTTPS
- 常用函数
- 常用的字符串函数
- 常用的数组函数
- 常用文件函数
- 常用时间函数
- 常用日历函数
- 常用url函数
- 面试题常见
- 时间戳
- 技术类文档
- 技术开发文档
- 开发环境
- 开发规范
- 注释规范
- 开发目录结构
- 数据库字典
- 路由
- 定时任务
- 获取系统配置
- 系统常用函数
- 后台表单
- 消息队列
- 第三方类库标注
- 需求文档
- 数据库
- MYSQL
- 事务(重点)
- 索引
- 存储过程
- 触发器
- 视图
- 导入导出数据库
- 优化mysql数据库的方法
- MyISAM与InnoDB区别
- 外连接、内连接的区别
- 物理文件结构
- MongoDB
- Redis
- 运用场景和实例
- pgsql
- 服务器
- Nginx
- 正向代理和反向代理
- 负载均衡
- Linux常用命令
- 基本目录和命令
- php开发工具
- phpStorm编辑器
- 安装和汉化
- 链接ftp
- 常用操作
- 常用快捷键
- 自定义快捷键
- 使用快捷键新建目录和文件
- 使用快捷键快速查找文件、类、方法
- 多文件切换
- 快速搜索设置项
- 多点编辑
- 方法重构
- 自定义文件模板和代码片段
- 自定义文件模板
- 自定义代码片段
- Xdebug 调试插件
- 安装Xdebug 调试插件
- 在PHPStorm 中使用 Xdebug 插件调试代码
- Vi Box虚拟机
- Vi Box 虚拟机 Oracle VM VirtualBox
- 虚拟机辅助工具一-Vagrant
- 华硕主板BIOS设置中VT虚拟化技术选项怎么开启 Oracle VM VirtualBox
- 沟通工具
- 文档分享
- 流程图
- 任务分配
- 代码托管
- 缺陷管理
- 设计图
- gitLab
- 安装
- 汉化
- Gitlab 用户和项目管理
- Gitlab 持续集成与自动构建实践
- PHP进阶
- 大流量解决方案
- PSR规范
- RESTFUL规范
- 设计模式
- 单例模式
- 策略模式
- 工厂模式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
- 外观模式
- 享元模式
- 代理模式
- 命令模式
- 中介者模式
- 观察者模式
- 状态模式
- 建筑者模式
- 适配器模式
- 桥接模式
- 装饰器模式
- 排序算法
- 冒泡排序算法
- 二分查找算法
- 直接插入排序算法
- 希尔排序算法
- 选择排序算法
- 快速排序算法
- 常见网络攻击类型
- CSRF攻击
- XSS攻击
- SQL注入
- Cookie攻击
- thinkphp
- thinkphp5命令行
- git
- Git 常用命令操作和基础学习
- 傻瓜与白痴的笔记本
- 学习
- 一、Git 与 GitHub 的来历
- 二、在 GitHub 上创建仓库
- 三、安装
- Windows 上安装 Git
- 安装2
- 四、克隆 GitHub 上的仓库到本地
- 五、GIT基本操作哦
- 六、Git 分支操作
- 一、添加SSH关联授权
- 二、为 Git 命令设置别名
- 三、Git 分支管理
- 七、多人协作 GitHub 部分
- 八、多人协作 Git 部分
- 九、Git tag 和 GitHub releases
- composer
- Composer 基础使用
- 安装和使用
- 在项目中集成PHPmailer
- 认识composer.json和composer.lock文件
- composer的其他命令操作
- 本地创建composer包
- 提交自己的依赖包到composer Packagist
- crontab计划任务
- Linux任务计划crontab
- php 的 计划任务——Crontab
- bootstrap前端框架
- 入门
- 实战技巧
- 后台模板样式——admin
- 第三方接口对接
- 微信
- 敏感词过滤
- 微信图片检测
- 短信类型
- 阿里云短信
- 容联云短信
- 飞鸽短信
- 媒体
- 新闻接口测试
- 免费新闻
- 免费视频
- nba赛事,未测试
- 豆瓣电影接口
- 音乐接口
- 网易短视频接口
- 知乎微信接口
- 百度ai
- 百度语音
- 图片识别
- 腾讯
- 腾讯im
- 腾讯云直播
- 腾讯滑动验证
- 物流快递
- 快递鸟、快递100
- 推送
- 极光推送
- 地图&天气
- 获取城市和天气预报
- 地址获取和定位
- 地址转换经纬度
- 图片类型
- 360新闻图片
- 多平台翻译
- 实名认证
- 七牛云
- 云合同
- 多站点收录查询接口
- 打印机
- 第三方登录
- 微信登录
- 支付
- 支付宝app支付
- 微信提现+退款
- 微信app支付
- 微信支付公式
- 类库
- 图片类
- phpqrcode实战:生成二维码
- 图片处理类
- 验证码类
- 消息类
- PHPMailer
- 分词类
- ik
- PHPAnalysis
- 自己封装的方法
- GD库
- 自动获取图片主题颜色
- 图片转素描
- 生成海报
- 图片转字符
- 验证码
- 图片转黑白灰
- GD库实现图片水印与缩略图
- Imagick扩展
- 将一张image图片转化为字符串的形式
- 基本方法
- 图片路径转base64
- 生成文件后缀图片
- url路径判断拼接
- 防篡改入口文件
- php中文姓名判断
- 可控抽奖
- 特殊截取
- 银行卡位(特殊卡号不支持)
- 微信红包计算
- 数组和对象互转
- php批量更新修改数据库
- base64_img上传
- 删库删目录————跑路
- 字符串特殊符号过滤
- 首字母转成默认头像
- 生成随机字符串
- 根据id转 邀请码
- 日志写入
- 字符串截取,超出显示省略号
- 清除html标签+清除html标签,字符串截取
- 计算时间差的函数和演示
- php判断路径是否是绝对路径,如果不是拼接至绝对路径
- sql 参数过滤
- php敏感词过滤
- 省市区分别截取
- 生成csv
- 无限极分类
- api接口返回封装的方法函数
- xml和数组互转
- 获取thinkph5下控制器和方法名
- 过滤
- 获取服务器信息
- php随机颜色
- 创建多级目录
- 推广码
- 跨域检测
- 二维码
- 文档类
- word
- PHPWord
- tcPdf
- MPDF
- dompdf
- FPDF、Fpdi类库
- excel
- PhpSpreadsheet导入
- phpExcel
- 时间
- PHP-农历+节气+节日等类库
- 时间类库
- 最好用的是人性化时间差
- 文件管理类
- 文件操作类
- 文件夹操作
- php操作ftp的类库
- curl
- 数据库操作类
- Db扩展函数
- 数据库备份
- 仿tp5的Db库
- 不常用mysql
- 自动生成数据库字典
- 字符串
- 字符串操作helper/Str
- 随机生成姓名
- 随机生成类
- php字符串类
- 中文转拼音的类库
- 分类
- 缓存
- 数据验证
- 身份证相关操作
- 安全类
- 表单生成类
- 自动生成表单,未完待续中