所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

ThinkPHP定时任务实现详细操作步骤 新手一看就会

ThinkPHP定时任务实现详细操作步骤 新手一看就会 一

文章目录CloseOpen

第一步:先把ThinkPHP的定时任务基础搭起来

别害怕“定时任务”这四个字,其实ThinkPHP的定时任务本质就是“用命令行执行一个PHP类”——和你写接口逻辑没区别,只是触发方式从“用户点按钮”变成了“命令行或服务器自动触发”。我把这一步拆成了“建类+测试”两个小步骤,保证你能看懂。

1.1 先建一个任务类——其实就是写个普通的PHP类

你得在项目里建一个“任务类”。我习惯把任务类放在application/common/command目录下(没有command文件夹就自己建一个),比如建个OrderStatTask.php(用来统计订单的任务类)。代码长这样:

<?php 

namespace appcommoncommand; // 对应文件路径:application/common/command

use thinkconsoleCommand;

use thinkconsoleInput;

use thinkconsoleOutput;

use thinkLog;

use thinkDb;

// 必须继承Command类——这是ThinkPHP定时任务的“入门券”

class OrderStatTask extends Command

{

// 配置任务的基本信息(比如名称、描述)

protected function configure()

{

$this->setName('order_stat') // 任务名称(后面命令行要用到)

->setDescription('每天统计昨日订单数量'); // 任务描述(方便自己记)

}

// 任务的核心逻辑——你要做的事都写在这里

protected function execute(Input $input, Output $output)

{

Log::record('订单统计任务开始:' . date('Y-m-d H:i:s'), 'info'); // 写日志

try {

//

  • 计算昨日的时间范围
  • $yesterdayStart = strtotime('-1 day 00:00:00');

    $yesterdayEnd = strtotime('-1 day 23:59:59');

    //

  • 统计昨日订单数量(假设订单表是order,创建时间字段是create_time)
  • $orderCount = Db::name('order')

    ->where('create_time', '>=', $yesterdayStart)

    ->where('create_time', '<=', $yesterdayEnd)

    ->count();

    //

  • 把统计结果存入统计表(假设统计表是order_stat)
  • Db::name('order_stat')->insert([

    'stat_date' => date('Y-m-d', $yesterdayStart), // 统计日期(昨日)

    'order_count' => $orderCount, // 订单数量

    'create_time' => time() // 记录创建时间

    ]);

    Log::record('昨日订单数量:' . $orderCount, 'info'); // 写日志

    $output->writeln('订单统计任务执行成功!'); // 命令行输出成功信息

    } catch (Exception $e) {

    // 如果执行失败,记录错误日志

    Log::record('订单统计任务失败:' . $e->getMessage(), 'error');

    $output->writeln('任务失败:' . $e->getMessage()); // 命令行输出错误信息

    return false; // 终止任务

    }

    Log::record('订单统计任务结束:' . date('Y-m-d H:i:s'), 'info'); // 写日志

    }

    }

    我给你拆解下关键细节:

  • 类名和路径要对应:比如OrderStatTask类文件必须放在application/common/command下,命名空间也要写appcommoncommand——我之前犯过“类名小写”的错(把OrderStatTask写成orderStatTask),结果命令行根本找不到这个类,改回首字母大写才解决;
  • configure方法setName里的“order_stat”是任务的“身份证”,后面执行命令时要用到;setDescription是给你自己看的,写清楚任务做什么,避免过段时间忘了;
  • execute方法:这是任务的“大脑”——你要统计订单、发推送,都写在这里。我 你第一次写时先写简单逻辑(比如往日志里写一行“任务执行了”),确认能跑通再替换成复杂逻辑,省得排查问题时找不到重点。
  • 1.2 用命令行测试——先确保本地能跑通

    类建好了,先别急着往服务器上放,先在本地终端测试——确保“类能被找到、逻辑能执行”。

    比如你的项目根目录是D:wwwthinkphp(Windows)或/www/thinkphp(Mac/Linux),步骤是:

  • 打开终端:Windows用cmd,Mac/Linux用Terminal;
  • cd到项目根目录:比如cd D:wwwthinkphp
  • 执行命令:输入php think order_stat(“order_stat”是你setName写的任务名称);
  • 看结果:如果终端输出订单统计任务执行成功!,同时runtime/log/今天的日期.log里有订单统计任务开始:2024-05-20 15:00:00这样的日志,说明成功了。
  • 如果失败,常见错误及解决办法:

    错误提示 原因 解决办法
    Class ‘appcommoncommandOrderStatTask’ not found 类文件路径或命名空间错了 检查类文件是不是在application/common/command下,命名空间是不是appcommoncommand
    Command “order_stat” is not defined. configure方法里的setName写错了 确认setName里的名称是“order_stat”,和命令行输入的一致
    PHP Fatal error: Uncaught Error: Class ‘thinkconsoleCommand’ not found 没装think-console依赖 执行composer require topthink/think-console(ThinkPHP 5.1及以上需要)

    我的小技巧:测试时如果遇到错误,先复制错误提示到百度搜——90%的问题别人都踩过坑。比如我之前遇到“Class not found”,就是因为把类文件放在了application/command而不是application/common/command,改个路径就好了。

    第二步:部署到服务器——Linux cron配置是关键

    本地跑通了,接下来要把任务放到服务器上——这一步的核心是配置Linux的cron服务(cron是Linux自带的定时工具,几乎所有项目都用它)。

    2.1 先搞懂cron的“语法”——五个星号不用怕

    cron的配置格式是 要执行的命令,五个星号分别代表“分、时、日、月、周”,比如:

  • :每分钟执行一次(用来测试);
  • 0 2 :每天凌晨2点执行(适合统计昨日数据);
  • 0 10 1:每周一上午10点执行(适合周统计);
  • 0 3 1 :每月1号凌晨3点执行(适合月统计)。
  • 如果记不住,可以用cron在线生成器(比如https://cron.qqe2.com/)——输入“每天凌晨2点执行”,它会自动生成0 2 ,比自己记靠谱。

    2.2 配置cron——手把手教你输命令

    接下来要在Linux服务器上操作(用Xshell、FinalShell这类SSH工具登录):

  • 查PHP的绝对路径:输入which php,终端会输出PHP的路径(比如/usr/local/php/bin/php)——一定要用绝对路径! 不然cron找不到PHP命令;
  • 编辑cron任务:输入crontab -e,打开文本编辑器(通常是vi);
  • 添加定时任务:在文件末尾加一行(替换成你的路径和任务名称):
  •  0 2   * /usr/local/php/bin/php /www/wwwroot/yourproject/think order_stat
    

    解释下每个部分:

  • /usr/local/php/bin/php:你服务器上PHP的绝对路径(用which php查的);

  • /www/wwwroot/yourproject/:你项目的根目录(比如你的ThinkPHP项目放在/www/wwwroot/shop,就写这个路径);

  • think:ThinkPHP的命令行入口文件(在项目根目录下,和applicationpublic同级);

  • order_stat:你任务的名称(setName写的)。
  • 保存退出:vi编辑器里按
  • Esc,输入:wq(保存并退出);
  • 查看任务:输入
  • crontab -l,如果能看到你刚才加的那一行,说明配置成功了。

    2.3 检查cron有没有执行——避免“配置了但没跑”

    配置完了,要验证任务有没有执行:

  • 看项目日志:去
  • runtime/log/今天的日期.log里找——如果有订单统计任务开始:2024-05-20 02:00:00,说明任务执行了;
  • 看cron系统日志:Linux会记录cron的执行情况——
  • CentOS/RHEL:输入
  • tail -f /var/log/cron,能看到May 20 02:00:01 server CROND[12345]: (root) CMD (/usr/local/php/bin/php /www/wwwroot/shop/think order_stat)这样的日志;

  • Ubuntu/Debian:输入
  • tail -f /var/log/syslog,找包含CRON的行。 我踩过的大雷:之前帮朋友配置时,把PHP路径写成了/usr/bin/php,但服务器上的PHP实际在/usr/local/php/bin/php——结果cron执行时找不到PHP,任务没跑。后来用which php查了路径,改对就好了。

    第三步:加“保险”——日志和报警不能少

    定时任务跑起来了,但别掉以轻心——要加监控,不然任务失败了你都不知道

    3.1 写详细日志——知道任务“干了什么”

    刚才的任务里我已经用了

    Log::record写日志,但我 你把每个关键步骤都写进去,比如“任务开始时间、统计的时间范围、统计结果、任务结束时间”——这样出问题时能快速定位。比如:

    php

    Log::record(‘订单统计任务开始:’ . date(‘Y-m-d H:i:s’), ‘info’); // 开始日志

    Log::record(‘统计的时间范围:’ . date(‘Y-m-d’, $yesterdayStart) . ‘ 00:00:00 到 ‘ . date(‘Y-m-d’, $yesterdayEnd) . ‘ 23:59:59’, ‘info’); // 时间范围日志

    Log::record(‘昨日订单数量:’ . $orderCount, ‘info’); // 结果日志

    Log::record(‘订单统计任务结束:’ . date(‘Y-m-d H:i:s’), ‘info’); // 结束日志

    日志存在

    runtime/log/今天的日期.log里,比如20240520.log——每天看一眼,心里有数。

    3.2 加报警——出问题能及时知道

    如果是重要任务(比如自动提现、发送会员通知),光写日志不够——万一任务失败了,你总不能每天守着日志看。这时候要加报警:任务失败时发邮件或短信给你。

    ThinkPHP自带Mail类,我教你怎么用:

  • 配置邮件参数:在
  • application/config.php里加:

    php

    'mail' => [

    'transport' => 'smtp', // 邮件传输方式(用smtp)

    'hostname' => 'smtp.qq.com', // QQ邮箱SMTP服务器(其他邮箱比如163是smtp.163.com)

    'port' => 465, // 端口(QQ邮箱是465,163是25)

    'secure' => 'ssl', // 加密方式(QQ邮箱是ssl,163是tls)

    'username' => 'your@qq.com', // 你的邮箱账号

    'password' => 'your_auth_code', // 邮箱授权码(不是登录密码!QQ邮箱在“设置-账户-开启SMTP服务”里获取)

    'from' => 'your@qq.com', // 发件人邮箱(和username一致)

    'from_name' => '定时任务报警', // 发件人名称(比如“订单统计任务报警”)

    ],

  • 在任务里加报警逻辑
  • php

    use thinkMail; // 引入Mail类

    protected function execute(Input $input, Output $output)

    {

    try {

    // 任务逻辑(和之前一样)

    } catch (Exception $e) {

    Log::record('任务失败:' . $e->getMessage(), 'error'); // 记录错误日志

    // 发送报警邮件

    Mail::send('email/error', ['error_msg' => $e->getMessage()], function ($message) {

    $message->to('yourname@163.com'); // 接收报警的邮箱(比如你的工作邮箱)

    $message->subject('订单统计任务失败报警'); // 邮件主题

    });

    $output->writeln('任务失败:' . $e->getMessage());

    return false;

    }

    }

    这里的

    email/error是邮件模板,放在application/index/view/email/error.html,内容可以是:

    html

    定时任务失败通知

    任务名称:订单统计任务

    失败时间:{$Think.datetime|date='Y-m-d H:i:s'}

    错误信息:{$error_msg}

    这样,任务失败时你会收到一封邮件,里面有详细的错误信息——不用每天查日志,出问题能及时处理。

    你按这些步骤试了吗2?我去年帮朋友配置时,就是用这个方法,从“不会写任务类”到“服务器上稳定运行”,只用了半天时间。如果遇到“类找不到”“cron不执行”或者“邮件发不出去”的问题,评论区告诉我——毕竟我踩过的坑,不想让你再踩一遍。


    本文常见问题(FAQ)

    ThinkPHP的定时任务类要放在哪个目录里?

    一般 放在application/common/command目录下(没有command文件夹的话自己新建一个就行)。比如你要写统计订单的任务类,就建个OrderStatTask.php放在这个目录里。得注意类的命名空间要和路径对应,比如命名空间得是appcommoncommand,不然命令行根本找不到这个类。

    命令行测试时提示“Command not defined”怎么解决?

    大概率是任务类里configure方法的setName写错了。比如你setName里写的是“order_stat”,命令行就得输“php think order_stat”,名称不一致肯定报错。另外也可能是类文件的路径或命名空间错了,比如类没放在application/common/command下,或者命名空间不是appcommoncommand,再检查一遍这些地方。

    Linux服务器上配置了cron但任务没执行,怎么排查?

    先查cron命令里的PHP路径对不对——得用绝对路径,比如用“which php”命令能查到服务器上的PHP路径(比如/usr/local/php/bin/php),别用相对路径。再看项目根目录对不对,比如你的项目在/www/wwwroot/shop,就不能写成/www/shop。还可以看cron的系统日志,CentOS/RHEL是/var/log/cron,Ubuntu/Debian是/var/log/syslog,里面会有执行记录,能找到没执行的原因。

    ThinkPHP定时任务的日志存在哪里?怎么看?

    日志存在项目的runtime/log目录下,文件名是当天的日期,比如20240520.log。打开日志文件就能看到任务的执行情况,比如“订单统计任务开始:2024-05-20 02:00:00”“昨日订单数量:123”这些内容,要是任务失败了,日志里也会有错误信息。

    报警邮件发不出去怎么处理?

    先检查邮箱配置参数对不对——比如SMTP服务器,QQ邮箱是smtp.qq.com,163邮箱是smtp.163.com;端口号QQ是465,163是25;密码得用邮箱的授权码(不是登录密码,QQ邮箱要在设置-账户里开启SMTP服务才能拿到)。再确认邮件模板的路径对不对,比如模板放在application/index/view/email/error.html,就不能写错路径,不然Mail类找不到模板也发不出邮件。

    原文链接:https://www.mayiym.com/51436.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码