本文目录导读:

在PHP项目中实现定时任务,主要有以下几种常见方式,我按照推荐程度和适用场景为你介绍:
✅ 推荐:系统Cron Job(Linux/Mac)
这是最可靠、最常用的方法,适用于生产环境。
基本用法
# 编辑crontab crontab -e # 每分钟执行一次PHP脚本 * * * * * /usr/bin/php /path/to/your/script.php # 每天凌晨2点执行 0 2 * * * /usr/bin/php /path/to/your/script.php # 每周一上午9点 0 9 * * 1 /usr/bin/php /path/to/your/script.php
PHP脚本示例
<?php
// /path/to/your/script.php
// 避免超时
set_time_limit(0);
// 执行任务
try {
// 你的业务逻辑
echo "任务开始执行: " . date('Y-m-d H:i:s') . "\n";
// 示例:清理过期数据
$db = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$db->exec("DELETE FROM temp_data WHERE expire_time < NOW()");
echo "任务执行完成\n";
} catch (Exception $e) {
// 记录错误日志
file_put_contents('/var/log/cron-error.log',
date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . "\n",
FILE_APPEND
);
}
🏢 企业级方案:任务调度器
适合复杂的定时任务管理。
Laravel任务调度(推荐)
Laravel提供了优雅的调度语法:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
// 基本调度
$schedule->command('emails:send')
->daily()
->at('13:00');
// 复杂调度
$schedule->call(function () {
// 清理逻辑
})->everyFiveMinutes()
->withoutOverlapping();
// 每分钟执行
$schedule->command('sync:data')
->everyMinute()
->runInBackground();
}
// 然后在服务器上添加一条cron
// * * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1
轻量级调度库
如果不使用框架,可以用 cron-expression 库:
// composer require mtdowling/cron-expression
use Cron\CronExpression;
$cron = CronExpression::factory('*/5 * * * *');
if ($cron->isDue()) {
// 执行任务
}
🔄 纯PHP实现:死循环检查
适合本地开发或简单场景:
<?php
// cron_runner.php
set_time_limit(0);
ignore_user_abort(true);
while (true) {
$now = time();
$lastRun = file_get_contents('/tmp/last_run.txt') ?: 0;
// 检查是否超过5分钟
if (($now - $lastRun) >= 300) {
try {
// 执行任务
echo date('Y-m-d H:i:s') . " - 执行定时任务\n";
// 记录执行时间
file_put_contents('/tmp/last_run.txt', $now);
} catch (Exception $e) {
error_log($e->getMessage());
}
}
// 每10秒检查一次
sleep(10);
}
🌐 云服务方案
使用外部服务
- EasyCron - 提供Web界面管理cron任务
- Cron-Job.org - 免费在线cron服务
- Google Cloud Scheduler - 企业级定时服务
- AWS CloudWatch Events - AWS生态集成
示例:使用Webhooks
// 创建API端点
Route::post('/webhook/cleanup', function () {
// 验证密钥
if (request('secret') !== env('CRON_SECRET')) {
abort(401);
}
// 执行清理
CleanupService::run();
return response()->json(['status' => 'success']);
});
🔍 Windows环境方案
Windows任务计划程序
# 创建计划任务 SchTasks /Create /SC MINUTE /MO 5 /TN "PHP Task" /TR "php.exe C:\path\to\script.php"
PHP服务方式
// 使用WScript运行
$WshShell = new COM("WScript.Shell");
$WshShell->Run("php schedule.php", 0, false);
⚡ 高性能方案:Worker模式
适合需要频繁执行的秒级任务:
<?php
// worker.php
// 使用pcntl扩展(仅支持Linux)
declare(ticks = 1);
// 信号处理
pcntl_signal(SIGTERM, function () {
exit(0);
});
// 进程池
$maxProcesses = 5;
$processes = [];
while (true) {
// 检查子进程数量
while (count($processes) >= $maxProcesses) {
foreach ($processes as $pid => $task) {
$result = pcntl_waitpid($pid, $status, WNOHANG);
if ($result > 0) {
unset($processes[$pid]);
}
}
usleep(100000); // 100ms
}
// 派生子进程执行任务
$pid = pcntl_fork();
if ($pid == -1) {
// fork失败
continue;
} elseif ($pid == 0) {
// 子进程执行任务
executeTask();
exit(0);
} else {
// 父进程记录子进程
$processes[$pid] = time();
}
sleep(1); // 每秒检查是否需要创建新进程
}
最佳实践建议
记录日志
function logCron($message, $level = 'info') {
$log = sprintf(
"[%s] [%s] %s\n",
date('Y-m-d H:i:s'),
strtoupper($level),
$message
);
file_put_contents('/var/log/php-cron.log', $log, FILE_APPEND);
}
防止重复执行
function acquireLock($taskName) {
$lockFile = "/tmp/{$taskName}.lock";
if (file_exists($lockFile)) {
$pid = file_get_contents($lockFile);
if (posix_kill($pid, 0)) {
return false; // 任务正在运行
}
}
file_put_contents($lockFile, getmypid());
return true;
}
function releaseLock($taskName) {
unlink("/tmp/{$taskName}.lock");
}
监控告警
// 在关键任务中添加
function notifyFailure($taskName, $error) {
// 发送邮件
mail('admin@example.com', "Cron Failed: $taskName", $error);
// 或者使用Slack Webhook
$data = json_encode(['text' => "❌ Cron任务 $taskName 失败: $error"]);
file_get_contents('https://hooks.slack.com/services/YOUR/WEBHOOK/URL',
false, stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $data
]])
);
}
选择建议
| 场景 | 推荐方案 |
|---|---|
| 个人项目/小站点 | 系统Cron + PHP脚本 |
| 企业级应用 | Laravel调度 + 系统Cron |
| 微服务架构 | 云服务调度器 |
| 需要秒级精度 | Worker模式 |
| 团队协作项目 | 框架内置调度 |
| 跨平台需求 | 第三方服务 |
核心建议:除非有特殊需求,否则使用系统cron + PHP框架的调度功能是最稳定、最容易维护的方案。