Linux下ThinkPHP5实现定时器任务 - 结合crontab
实例一:
1.在/application/command创建要配置的PHP类文件,需要继承Command类,并重写configure和execute两个方法,例如:
<?php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
class Test extends Command
{// 配置定时器的信息protected function configure(){$this->setName('test')->setDescription('Command Test');}protected function execute(Input $input, Output $output){// 输出到日志文件$output->writeln("TestCommand:");// 定时器需要执行的内容// .....$output->writeln("end....");}
}
2.修改application/command.php内容,加入上述的定时器内容
<?php
return ['application\command\Test', // 加入需要cmd运行的PHP文件
];
3.添加shell执行文件
在项目根目录下创建shell脚本,例如crond.sh
#!/bin/sh
PATH=/usr/local/php/bin:/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # 将php路径加入都临时变量中
cd /home/wwwroot/域名/ # 进入项目的根目录下,保证可以运行php think的命令
php think test # 执行在Test.php设定的名称
注意:test 可执行命令是ThinkPHP自带的,可以通过 连接服务器,到/home/wwwroot/域名/ 目录下,输入 php think查询可以被执行的命令,如下:
4.使用crontab设置定时器
有两种方式,效果是一样的:
1.连接到服务器,输入 crontab -e,写入:
0 0 * * * /home/wwwroot/域名/crond.sh
注意:1).0 0 * * * 是crontab的定时表达式,表示每天的0点0分执行该文件,具体详情可以访问《crontab定时写法》进行学习。
2).可以使用crontab -l 的命令查看已登录的账户有几个定时器。
3).可以到 /var/log/cron 文件查看日志文件,便于追踪错误。
2.连接到服务器,输入 vim /etc/crontab, 初始化内容为:
在该文件写入
0 0 * * * root /home/wwwroot/域名/crond.sh
最终的查看的结果是:
最后保存该文件
5.重启crond服务
service crond restart
如果 该命令无法重启,请使用systemctl restart crond 进行重启。
发现还有一个方法,需要修改本文的前三步,后面均一致。
1).新增Controller类,并编写相对应的方法,例如:
<?phpnamespace app\demo\controller;use think\Controller;
use think\Log;class Test extends Controller
{public function test(){Log::error('start test crond demo.....');Log::error('end test crond demo.....');}}
访问test方法的路由:demo/test/test
2).添加shell执行文件
在项目根目录下创建shell脚本,例如crond.sh
#!/bin/sh
PATH=/usr/local/php/bin:/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# 1.执行 php 命令不需要到thinkphp项目的目录下 2.index.php为入口文件 3.第三个参数为需要执行方法的路由
php /home/wwwroot/域名/index.php demo/test/test
后面的步骤从本文第4步开始,就可以完成定时功能。
个人意见:第二种方法符合API引用的思维,觉得比较容易被接受,第一种有点引用插件的感觉,对于刚接触项目的用户友好一点,可以知道项目的定时器;因此个人觉得这两种都可以,看个人习惯。
实例二:可后台自定义定时任务
PHP函数:https://blog.csdn.net/meimeieee/article/details/79556191
Linux crontab:https://www.cnblogs.com/longjshz/p/5779215.html
第一种:PHP函数
这个可根据业务需求在项目后台做成配置页面,运营人员也可配置。
<?php//开始任务public function startCrond($id) {Db::name('crond')->where(['id' => $id])->setField('run', 1);$this->execCrond($id);}//终止任务public function abortCrond($id) {Db::name('crond')->where(['id' => $id])->setField('run', 0);}//执行任务public function execCrond($id) {ignore_user_abort(); //关掉浏览器,PHP脚本也可以继续执行.set_time_limit(0); // 通过set_time_limit(0)可以让程序无限制的执行下去do {$crond_info = Db::name('crond')->where(['id' => $id])->find();if (!$crond_info['run']) {die('process abort'); //终止任务}if (1 == $crond_info['type']) {//每过多少秒执行一次file_get_contents($crond_info['command']);Db::name('crond')->where(['id' => $crond_info['id']])->setInc('exec_count'); //自增累计执行次数sleep($crond_info['interval']); // 间隔} elseif (2 == $crond_info['type']) {//每天只执行一次$newDate = date("H:i"); //获取当前时分,比对if ($crond_info['interval'] == $newDate) {file_get_contents($crond_info['command']);Db::name('crond')->where(['id' => $crond_info['id']])->setInc('exec_count'); //自增累计执行次数sleep(3600 * 24); // 间隔} else {sleep(60); // 间隔}}} while (true);}//任务1public function testCrond1() {Db::name('test')->insert(['crond_id' => '1', 'date' => date('YmdHis')]);}//任务2public function testCrond2() {Db::name('test')->insert(['crond_id' => '2', 'date' => date('YmdHis')]);}//任务3public function testCrond3() {Db::name('test')->insert(['crond_id' => '3', 'date' => date('YmdHis')]);}
CREATE TABLE `bs_crond` (`id` int(11) NOT NULL AUTO_INCREMENT,`type` tinyint(2) NOT NULL DEFAULT '1' COMMENT '1、以秒为周期,2、以天为周期',`interval` varchar(30) DEFAULT NULL COMMENT 'type=1:间隔秒数,type=2:每天的执行时间时分 示例12:10',`command` varchar(100) NOT NULL COMMENT '任务',`path` varchar(100) DEFAULT NULL,`exec_count` int(11) DEFAULT '0' COMMENT '累计执行统计',`run` varchar(10) DEFAULT '0' COMMENT '是否开始 1、正常执行,0、终止',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=191 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='周期任务';CREATE TABLE `test` (`id` int(11) NOT NULL AUTO_INCREMENT,`crond_id` int(11) DEFAULT NULL,`date` datetime DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=352 DEFAULT CHARSET=utf8mb4 COMMENT='测试表';
执行结果:
crontab的基本格式:
f1 f2 f3 f4 f5 command
分 时 日 月 周 命令
第一列f1代表分钟1~59:当f1为*表示每分钟都要执行;为*/n表示每n分钟执行一次;为a-b表示从第a分钟到第b分钟这段时间要执行;为a,b,c,...表示第a,b,c分钟要执行
第二列f2代表小时0~23(0表示凌晨):当f2为*表示每小时都要执行;为*/n表示每n小数执行一次;为a-b表示从第a小时到第b小时这段时间要执行;为a,b,c,...表示第a,b,c小时要执行
第三列f3代表日1~31:含义如上所示,以此类推
第四列f4代表月1~12:含义如上所示,以此类推
第五列f5代表星期0~6(0表示星期天):含义如上所示,以此类推
第六列command代表要运行的命令
命令参数:
crontab -l 在标准输出上显示当前的crontab
crontab -r 删除当前的crontab文件
crontab -e 编辑当前的crontab文件
相关文章:

Linux下ThinkPHP5实现定时器任务 - 结合crontab
实例一: 1.在/application/command创建要配置的PHP类文件,需要继承Command类,并重写configure和execute两个方法,例如: <?php namespace app\command; use think\console\Command; use think\console\Input; use think\cons…...

3dsmax模型烘焙光照贴图并导入unity流程详解
目录 前言 软件环境 前置知识储备 一、模型场景搭建 二、模型材质处理 三、vray渲染准备 四、烘焙至贴图 五、unity场景准备 六、贴图与材质 前言 该流程针对某些固定场景(模型发布、无法使用实时渲染引擎等)情况下的展示,本文记录烘…...

安卓生成公钥和md5签名
安卓公钥和md5证书签名 大家好,最近需要备案app,用到了公钥和md5,MD5签名我倒是知道,然而对于公钥却一下子不知道了, 现在我讲一下我的流程。 首先是md5证书签名的查看, 生成了apk和签名.jks后&…...

pwndbg安装(gdb插件)
pwndbg安装(gdb插件) 源地址:https://github.com/pwndbg/pwndbg 手动安装 git clone https://github.com/pwndbg/pwndbg cd pwndbg ./setup.sh 没啥问题运行gdb的话就可以看到明显的不同了 如果安装成功了,但没有生效 如果有问…...

SpringBoot 学习(二)配置
2. SpringBoot 配置 2.1 配置文件类型 配置文件用于修改 SpringBoot 的默认配置。 2.1.1 properties 文件 **properties ** 是属性文件后缀。 文件名:application.properties 只能保存键值对。 基础语法:keyvalue namewhy注入配置类 Component //…...
西门子828d授权密钥破解经验分享 I7I54833762
操作数组的方法 Array.prototype.toSorted(compareFn) //返回一个新数组,其中元素按升序排序,而不改变原始数组。 Array.prototype.toReversed() //返回一个新数组,该数组的元素顺序被反转,但不改变原始数组。 Array.prototype.to…...
06贪心:跳跃游戏
06贪心:跳跃游戏 55. 跳跃游戏 刚看到本题一开始可能想:当前位置元素如果是 3,我究竟是跳一步呢,还是两步呢,还是三步呢,究竟跳几步才是最优呢? 其实跳几步无所谓,关键在于可跳的…...
鄙视测试,理解测试,成为测试
首先,其实题主的问题还是很实诚的,我刚开始做测试的时候其实也是这个心态,想转开发,也学习了很多的语言,个人觉得这是职业危机感的表现,挺好的,也相信题主不管去做开发和测试都会去不断的学习和…...

MySQL数据库基础知识要点总结
目录 前言 一.数据库构成 1.1 表 1.2 关系 1.3 索引 1.4 查询语言 1.5 数据库管理系统 二.数据类型 2.1 整数 2.2 浮点 2.3 日期与时间 2.4 字符串 三.约束条件 3.1 主键约束 3.2 唯一约束 3.3 外键约束 3.4 非空约束 3.5 默认值约束 总结 前言 数据库是…...

基础运维(一)YUM仓库
一 自定义YUM仓库 1 Yum仓库特点 作为yum源需要准备的内容 大量的rpm 软件安装包文件针对这些软件包的 repodata/ 仓库档案 repodata/ 仓库档案数据 filelists.xml.gz // 软件包的文件安装清单primary.xml.gz // 软件包的基本/主要信息other.xml.gz // 软件包…...

递归算法讲解,深度理解递归
首先最重要的就是要说明递归思想的作用,在后面学习的高级数据接口,树和图中,都需要用到递归,即深度优先搜索,如果递归掌握的不好,后面的数据结构将举步为艰。 加油 首先看下如何下面两个方法有什么区别&a…...

网络通信(套接字通信)(C/C++)
1.网络编程必知概念 1.广域网和局域网 广域网:又称外网、公网。是连接不同地区局域网或城域网进行计算机通信的远程公共网络。 局域网:在一定的通信范围内,有很个多计算机组成的私有网络就叫局域网。(这些计算机相互之间是可以通信的,但是不能直接访问外网(可以通过网线…...

anaconda navigator启动时一直卡在 loading applications 页面
anaconda navigator启动时一直卡在 loading applications 页面 方法1 在安装目录找到D:\anaconda\Lib\site-packages\anaconda_navigator\api 然后打开conda_api.py, 在1358行找到data yaml.load(f),将其改为data yaml.safeload(f) 猜测为保证代码…...

力扣刷题-链表-删除链表的倒数第N个节点
19.删除链表的倒数第N个节点 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5] 示例 2:输入:head [1], n 1 输出&…...

Blender DreamUV插件使用简明教程
DreamUV 是一个可让你在Blender的 3D 视口中操纵 UV的工具集合。 该工具集设计用于可重复使用的纹理,例如平铺纹理、装饰表和纹理图集。 其目的是让你无需退出 3D 视图即可对几何体进行纹理处理,从而节省时间并提高灵活性。 1、安装DreamUV 首先下载为…...

AI在线工具分享
1、ChatGPT ChatGPT是一种由OpenAI训练的大型语言模型。它的原理是基于Transformer架构,通过预训练大量文本数据来学习如何生成人类可读的文本,然后通过接受输入并生成输出来实现对话。 ChatGPT的用途非常广泛,可以用于自然语言处理…...
Matlab批量处理测试数据的方法:以VCO的调谐测试曲线处理为例
我们都知道得到的VCO调谐曲线是一根一根扫出来的,如果要手动对数据进行处理很麻烦。 (当然最好是搭建一个自动化测试平台,一边测试一边把数据抓取了,这个以后可以搞一下再更新) 目前还是手动测量的情况下,…...

VScode断点调试vue
VScode断点调试vue 1、修改launch.js文件(没有这个文件就新建)。 {// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information, visit: https://go.microsoft.com/fwlin…...
20吨屠宰鸡鸭鹅一体化污水处理设备加工厂家
20吨屠宰鸡鸭鹅一体化污水处理设备加工厂家 溶气气浮机主要构造说明 气浮系统气浮系统集进水、絮凝、分离、集水、出水于一体,与传统气浮设备类似,设有一个稳流室、溶气释放室,使处理性能更稳定,效果更优越。 稳定室:通…...
android被杀以后fragments缓存重建问题和测试方法
这个问题,其实不是太好复现。因为在android的缓存Fragment机制是写在androidx的库中。 主要的原因是android Framework机制: framework at yourpackage.onSaveInstanceState(XXXActivity.kt:118) at android.app.Activity.performSaveInstanceState(A…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...