PHP 怎么定时器事件

wen PHP项目 2

本文目录导读:

PHP 怎么定时器事件

  1. 命令行方式(最常用)
  2. 使用 pcntl 扩展(仅 Unix/Linux)
  3. 使用 Swoole 扩展(高性能异步)
  4. 使用 Workerman 或其他框架
  5. 纯 PHP 循环实现(不推荐)
  6. 使用队列系统(适合分布式)
  7. Web 方式(被动触发)
  8. 使用异步非阻塞方案
  9. 选择建议
  10. 注意事项

在 PHP 中实现定时器事件有多种方式,我为你整理了从简单到复杂的方案:

命令行方式(最常用)

PHP 脚本 + Cron Job(Linux/Mac)

// /path/to/your_script.php
<?php
// 要做的事情
file_put_contents('/var/log/cron.log', date('Y-m-d H:i:s') . " - 任务执行\n", FILE_APPEND);
# Crontab 配置(每5分钟执行)
*/5 * * * * /usr/bin/php /path/to/your_script.php
# 每天凌晨2点执行
0 2 * * * /usr/bin/php /path/to/your_script.php
# 每小时执行一次
0 * * * * /usr/bin/php /path/to/your_script.php

Windows 任务计划程序

:: 创建批处理文件 run_task.bat
@echo off
C:\php\php.exe D:\path\your_script.php

使用 pcntl 扩展(仅 Unix/Linux)

<?php
declare(ticks = 1);
function signal_handler($signal) {
    echo "收到信号: $signal\n";
    // 执行定时任务
    sendEmail();
}
// 注册信号处理器
pcntl_signal(SIGALRM, "signal_handler");
while (true) {
    // 设置10秒后的定时器
    pcntl_alarm(10);
    // 做一些其他工作
    echo "程序运行中...\n";
    sleep(1);
}

使用 Swoole 扩展(高性能异步)

<?php
// Swoole 定时器(毫秒级)
$timer = new Swoole\Timer;
// 每2秒执行一次
$timerId = $timer->tick(2000, function () {
    echo "2秒定时器触发\n";
    // 执行任务
    processTask();
});
// 5秒后执行一次
$timer->after(5000, function () use ($timerId) {
    echo "5秒后执行一次\n";
    $timer->clear($timerId); // 清除定时器
});

使用 Workerman 或其他框架

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Timer;
use Workerman\Worker;
$worker = new Worker('tcp://0.0.0.0:2345');
$worker->onWorkerStart = function ($worker) {
    // 每10秒执行一次
    Timer::add(10, function () {
        echo "定时任务执行\n";
        // 你的业务逻辑
    });
};
Worker::runAll();

纯 PHP 循环实现(不推荐)

<?php
// 简单的循环定时器
$interval = 5; // 5秒
$lastTime = time();
while (true) {
    if (time() - $lastTime >= $interval) {
        $lastTime = time();
        echo "执行定时任务\n";
        // 你的任务代码
    }
    sleep(1);
}

使用队列系统(适合分布式)

Laravel 计划任务

// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->call(function () {
        // 每天执行的任务
        DB::table('users')->update(['status' => 1]);
    })->daily();
    $schedule->command('emails:send')
        ->everyFiveMinutes();
}

Web 方式(被动触发)

<?php
// cron.php - 通过 web 请求触发
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['secret']) && $_POST['secret'] === 'your_secret') {
    // 执行定时任务
    processTasks();
    echo "任务执行成功";
}

使用异步非阻塞方案

<?php
// ReactPHP 示例
require __DIR__ . '/vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$loop->addPeriodicTimer(5, function () {
    echo "每5秒执行\n";
});
$loop->addTimer(60, function () {
    echo "60秒后执行一次\n";
});
$loop->run();

选择建议

场景 推荐方案
常规定时任务 Cron Job
需要毫秒级精度 Swoole / ReactPHP
异步高性能场景 Swoole / Workerman
分布式系统 消息队列(Redis/Beanstalkd)
Web应用 框架自带的调度器
简单脚本 sleep() + 循环

注意事项

  1. PHP 执行超时:长时间运行的脚本可能触发 max_execution_time,需要设置:

    set_time_limit(0); // 不限制执行时间
    ignore_user_abort(true); // 用户断开连接继续执行
  2. 内存管理:长时间运行要注意内存泄漏:

    while (true) {
     // 执行任务
     gc_collect_cycles(); // 定期清理垃圾
     memory_get_usage(); // 监控内存
    }
  3. 日志记录:记录执行日志便于调试:

    error_log("任务执行于 " . date('Y-m-d H:i:s'), 3, '/var/log/task.log');

选择哪种方案取决于你的具体需求:如果是简单的定时任务,Cron是最佳选择;如果需要高性能异步处理,建议使用Swoole。

抱歉,评论功能暂时关闭!