TP6定时任务 2025-09-05

第一步,创建一个自定义命令类文件,运行指令

php think make:command Timing

会生成一个app\command\Timing 命令行指令类,根据实际项目内容修改如下示例:

<?php

/**
 * 定时任务命令行工具
 *
 * 本文件定义了一个ThinkPHP命令行命令,用于执行系统定时任务。
 * 可通过系统crontab配置定期调用,实现自动化业务处理。
 */

// 开启严格类型模式,确保方法参数和返回值类型严格匹配,提升代码健壮性
declare(strict_types=1);

// 定义命令类所在的命名空间,符合ThinkPHP应用的组织结构
namespace app\command;

// 引入ThinkPHP命令行基础类
use think\console\Command;     // 命令行命令基类,所有自定义命令必须继承此类
use think\console\Input;       // 输入处理类,用于获取命令行参数和选项
use think\console\Output;      // 输出处理类,用于向控制台输出信息
use think\console\input\Argument;  // 参数定义类,用于定义位置参数
use think\console\input\Option;    // 选项定义类,用于定义命名选项参数
use think\facade\Log;          // 日志门面,用于记录执行日志(可选)

/**
 * 定时任务执行命令类
 *
 * 该类继承自ThinkPHP的Command基类,用于创建可被调用的定时任务命令。
 * 通过系统cron配置定期执行,实现自动化业务处理。
 *
 * @package app\command
 */
class Timing extends Command
{
    /**
     * 配置命令基本信息
     *
     * 该方法在命令注册时被框架调用,用于设置命令的名称、描述、参数和选项等信息。
     * 这些信息会在执行 `php think list` 时显示在命令列表中。
     *
     * @return void
     */
    protected function configure(): void
    {
        // 设置命令名称,在命令行中通过 `php think timing` 调用
        $this->setName('timing')
            // 设置命令描述,显示在命令列表中便于识别命令用途
            ->setDescription('执行系统定时任务,包括数据清理、统计报表生成等自动化作业')
            // 添加命令参数定义(示例:可选的执行模式参数)
            // 参数格式:Argument::create('参数名', '模式', '描述', '默认值')
            // 模式:Argument::REQUIRED(必填) 或 Argument::OPTIONAL(可选)
            ->addArgument('mode', Argument::OPTIONAL, '任务执行模式(test-测试模式, force-强制模式)', 'normal')
            // 添加命令选项定义(示例:是否跳过某些任务的选项)
            // 选项格式:Option::create('选项名', '简写', '模式', '描述', '默认值')
            // 模式:Option::VALUE_REQUIRED(必须值), Option::VALUE_OPTIONAL(可选值),
            //       Option::VALUE_NONE(无值,作为开关使用)
            ->addOption('skip-clean', null, Option::VALUE_NONE, '跳过数据清理任务')
            ->addOption('verbose', 'v', Option::VALUE_NONE, '显示详细执行信息');
    }

    /**
     * 执行命令的主要逻辑
     *
     * 当用户在命令行中运行 `php think timing` 时,该方法会被自动调用。
     * 包含完整的定时任务业务逻辑,建议将不同任务模块化处理。
     *
     * @param Input $input 输入对象,用于获取命令行输入的参数和选项值
     * @param Output $output 输出对象,用于向控制台输出执行信息和结果
     * @return int 返回执行状态码:0-成功,1-失败(遵循Unix惯例)
     */
    protected function execute(Input $input, Output $output): int
    {
        // 输出开始执行提示信息,使用info样式显示绿色文本
        $output->writeln('<info>🚀 开始执行定时任务...</info>');

        // 获取命令行参数和选项值
        $executionMode = $input->getArgument('mode');      // 获取模式参数
        $isSkipClean = $input->getOption('skip-clean');    // 获取是否跳过清理的选项
        $isVerbose = $input->getOption('verbose');         // 获取是否显示详细信息的选项

        // 显示当前执行配置(在详细模式下显示)
        if ($isVerbose) {
            $output->writeln("📋 执行模式: {$executionMode}");
            $output->writeln("⏭️  跳过清理: " . ($isSkipClean ? '是' : '否'));
        }

        try {
            // 记录开始时间,用于计算任务执行耗时
            $startTime = microtime(true);

            // ======================= 任务执行区域开始 =======================

            // 任务1: 执行数据清理(除非指定了跳过清理选项)
            if (!$isSkipClean) {
                $output->writeln('🧹 开始执行数据清理任务...');
                $this->cleanupData();  // 调用数据清理方法
                $output->writeln('<comment>✅ 数据清理完成</comment>');
            } else {
                $output->writeln('<comment>⏭️  跳过数据清理任务</comment>');
            }

            // 任务2: 生成每日统计报表
            $output->writeln('📊 开始生成统计报表...');
            $reportResult = $this->generateReports();  // 调用报表生成方法
            $output->writeln("<comment>✅ 报表生成完成: {$reportResult}条记录</comment>");

            // 任务3: 发送通知邮件(仅在非测试模式下执行)
            if ($executionMode !== 'test') {
                $output->writeln('📧 开始发送通知邮件...');
                $sentCount = $this->sendNotifications();  // 调用邮件发送方法
                $output->writeln("<comment>✅ 邮件发送完成: {$sentCount}封</comment>");
            }

            // ======================= 任务执行区域结束 =======================

            // 计算并显示总执行时间
            $executionTime = round(microtime(true) - $startTime, 2);
            $output->writeln("<info>🎉 所有定时任务执行完成!耗时: {$executionTime}秒</info>");

            // 记录成功日志(可选)
            Log::info("定时任务执行成功 - 模式: {$executionMode}, 耗时: {$executionTime}秒");

            // 返回成功状态码
            return 0;

        } catch (\Exception $e) {
            // 捕获执行过程中抛出的异常
            $errorMessage = "❌ 定时任务执行失败: " . $e->getMessage();

            // 输出错误信息到控制台(红色文本)
            $output->writeln("<error>{$errorMessage}</error>");

            // 记录详细错误日志,包含堆栈跟踪信息
            Log::error("定时任务执行失败: " . $e->getMessage(), [
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            ]);

            // 返回失败状态码 1
            return 1;
        }
    }

    /**
     * 执行数据清理任务
     *
     * 清理过期缓存、临时文件、无效数据等
     * 实际项目中应根据具体业务需求实现
     *
     * @return void
     */
    private function cleanupData(): void
    {
        // 示例:清理过期缓存
        // Cache::clearExpired();

        // 示例:删除临时文件
        // $this->deleteTempFiles();

        // 示例:清理数据库中的软删除记录
        // Model::where('delete_time', '<', time() - 30*86400)->delete();

        // 模拟清理操作耗时
        sleep(1);
    }

    /**
     * 生成统计报表
     *
     * 生成各种业务统计报表,如每日订单统计、用户活跃度等
     *
     * @return int 返回生成的报表记录数
     */
    private function generateReports(): int
    {
        // 示例:生成每日订单统计
        // $orderCount = Order::whereDate('create_time', date('Y-m-d'))->count();

        // 示例:生成用户活跃度报表
        // $activeUsers = User::where('last_login_time', '>', time() - 86400)->count();

        // 模拟报表生成操作,返回生成的记录数
        sleep(2);
        return 15; // 模拟生成15条报表记录
    }

    /**
     * 发送通知邮件
     *
     * 向相关人员发送任务执行结果通知
     *
     * @return int 返回成功发送的邮件数量
     */
    private function sendNotifications(): int
    {
        // 示例:发送邮件通知
        // $mailer = new Mailer();
        // $sent = $mailer->sendDailyReport();

        // 模拟邮件发送操作
        sleep(1);
        return 3; // 模拟发送3封邮件
    }
}

第二步,配置config/console.php文件

<?php
return [
    'commands' => [
        'timing' => 'app\command\Timing',
    ]
];

第三步,测试,运行命令

php think timing

第四步,添加定时计划任务,具体百度下如何添加计划任务一大堆

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容