Set Up Cron Jobs to Run PHP Scripts on DirectAdmin

Cron 作业是一个预定任务,可在设定的间隔自动运行脚本或命令。常见用途包括发送每日电子邮件、在夜间清除缓存、运行数据库备份或按计划触发 PHP 脚本。本分步指南向您展示如何在 DirectAdmin 虚拟主机上配置 Cron 作业以自动运行 PHP 脚本。

什么是 Cron 作业?

Cron 是 Linux 上的基于时间的作业调度程序,以定义的间隔自动运行任务。调度使用具有五个字段的 Cron 表达式:

* * * * * 命令
│ │ │ │ └── 星期几 (0-7, 0/7 = 星期日)
│ │ │ └──── 月份 (1-12)
│ │ └────── 月份中的日期 (1-31)
│ └──────── 小时 (0-23)
└────────── 分钟 (0-59)

常见 Cron 表达式示例

常见日程的 Cron 表达式参考

除了五字段语法基础外,这里是在真实虚拟主机场景中使用的表达式的实用参考表,以及其典型用例:

表达式 日程 典型用例
*/5 * * * * 每 5 分钟 队列处理、WP-Cron 替代
0 */6 * * * 每 6 小时 数据同步、缓存清除
0 2 * * * 每天 02:00 夜间数据库备份
0 9 * * 1-5 周一–周五 09:00 每日商务报告电子邮件
0 0 1,15 * * 每月 1 号和 15 号 半月发票生成
0 23 * * 0 每周日 23:00 每周完整网站备份

不确定语法?使用免费的 Cron 表达式生成器 — 用普通英文输入你想要的日程,立即获得正确的表达式。

在 DirectAdmin 中设置 Cron 作业

  1. 登录 DirectAdmin
  2. 转到高级功能 → Cron 作业
  3. 填入分钟 / 小时 / 日期 / 月份 / 星期几字段
  4. 输入要运行的命令
  5. 点击添加

运行 PHP 脚本的命令

格式 1 — 直接 PHP 二进制文件

/usr/local/php83/bin/php /home/username/public_html/cron/script.php

格式 2 — php-cli

/usr/bin/php /home/username/public_html/cron/script.php

格式 3 — wget(基于 HTTP 的 Cron)

wget -q -O /dev/null "https://yourdomain.com/cron/run.php" > /dev/null 2>&1

格式 4 — curl

curl -s "https://yourdomain.com/cron/run.php" > /dev/null 2>&1

提示:始终为 PHP 二进制文件和脚本文件使用完整绝对路径。Cron 在最小环境中运行,没有与普通 shell 会话相同的 PATH 变量。如果不确定 PHP 二进制路径,请在 SSH 中运行 which php。

编写 Cron 友好的 PHP 脚本

设计为通过 cron 运行的脚本应处理锁定、错误报告和与 Web 请求的环境差异。以下是三个最重要的模式:

使用锁文件防止重叠运行

如果您的 cron 每 5 分钟触发一次,但脚本需要 8 分钟完成,第二个实例将在第一个实例完成之前启动,可能导致数据损坏或重复工作。

<?php
$lockFile = '/home/username/cron.lock';
if (file_exists($lockFile)) {
    // If lock is older than 10 minutes, it is stale — remove it
    if (time() - filemtime($lockFile) < 600) {
        exit("Script already running\n");
    }
}
file_put_contents($lockFile, getmypid());

try {
    // ... main work ...
} finally {
    unlink($lockFile); // always remove lock, even on error
}

捕获错误并发送警报

Cron 作业是隐形的 — 它们在后台运行,除非构建错误处理,否则会无声地失败。在每个 cron 脚本顶部添加此块:

<?php
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    $msg = date('Y-m-d H:i:s')." ERROR [$errno] $errstr in $errfile:$errline\n";
    file_put_contents('/home/username/cron-error.log', $msg, FILE_APPEND);
    mail('[email protected]', 'Cron Error Alert', $msg);
});

register_shutdown_function(function() {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR])) {
        $msg = date('Y-m-d H:i:s')." FATAL: ".$error['message']."\n";
        file_put_contents('/home/username/cron-error.log', $msg, FILE_APPEND);
    }
});

设置正确的时区

Cron 在服务器时区运行,通常是 UTC。如果您的日程逻辑取决于本地时间,请在脚本顶部明确设置时区:

<?php
date_default_timezone_set('Asia/Bangkok'); // UTC+7

// For database operations, also set MySQL timezone:
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$pdo->exec("SET time_zone = '+07:00'");
echo date('Y-m-d H:i:s'); // Bangkok local time

实际 Cron 作业示例

在 08:00 发送每日报告电子邮件

0 8 * * * /usr/bin/php /home/username/public_html/send-email.php

每晚午夜清除缓存

0 0 * * * /usr/bin/php /home/username/public_html/clear-cache.php

用真实 Cron 作业替换 WP-Cron

添加到 wp-config.php:define('DISABLE_WP_CRON', true);

然后添加此 Cron 作业:

*/5 * * * * /usr/bin/php /home/username/public_html/wp-cron.php > /dev/null 2>&1

共享虚拟主机限制及其解决方法

共享虚拟主机的约束与 VPS 显著不同。提前了解它们将为您节省生产中的意外故障。

约束 共享虚拟主机现实 解决方案
最小频率 每 1 分钟(DirectAdmin) 足够满足大多数任务
执行超时 通常限制在 60–300 秒 在脚本中添加 set_time_limit(0)
内存限制 根据套餐 128–512 MB 运行 php -d memory_limit=256M
输出处理 未重定向的输出可能会发送电子邮件给 crontab 所有者 对每条命令追加 > /dev/null 2>&1
PATH 环境 Cron 以最小 PATH 启动 — 二进制文件可能无法解析 始终为 PHP 二进制文件和脚本使用绝对路径

对于运行时间超过 5 分钟、消耗大量内存或需要每分钟运行多次的脚本,请考虑升级到 VPS,在 VPS 上没有共享资源限制,您可以使用完整的系统 crontab。

验证您的 Cron 作业运行

让您的脚本每次执行时都写一个日志条目,以便之后验证:

<?php
file_put_contents('/home/username/cron.log',
    date('Y-m-d H:i:s') . " - Script ran\n", FILE_APPEND);
// ... your script code

具有完整 Cron 作业支持的虚拟主机

AsiaGB 虚拟主机通过 DirectAdmin 支持 Cron 作业,PHP 7.4 / 8.2 / 8.3。从 500 泰铢/年起,提供 99% 正常运行时间。

查看虚拟主机套餐

查看泰国虚拟主机全部套餐 →