首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 管理 Crontab 計劃任務實戰:php-crontab-manager 與 SSH2 遠程操作完整指南

     編輯:PHP 相關知識

前言

在 PHP 應用中動態管理 Linux Crontab 任務(新增、修改、刪除、查看)是自動化運維的常見需求。本文介紹兩種主流方案:本機執行 php-crontab-manager 庫(PHP 5.3+)、遠程 SSH2 操作 Ssh2_crontab_manager 類,並涵蓋安裝、API 使用、權限控制與安全最佳實踐。

一、方案一:php-crontab-manager(本機/同權限執行)

1. 安裝

composer require mediovski/php-crontab-manager

需 PHP ≥ 5.3,執行 PHP 的用戶需擁有 crontab 指令權限(通常為 www-data 或對應 FPM 用戶)。

2. 核心 API 速查

use Mediovski\Crontab\CrontabManager;

$crontab = new CrontabManager();

// 載入現有 crontab(指定檔案或自動讀取當前用戶)
$crontab->enableOrUpdate('/tmp/my/crontab.txt'); // 或 $crontab->load();

// 新增任務
$job = $crontab->newJob();
$job->on('* * * * *')          // 每分鐘
    ->doJob('/usr/bin/php /var/www/artisan schedule:run');
$crontab->add($job);

// 批次新增(鏈式)
$job->onMinute('20-30')->doJob("echo 'foo'");
$crontab->add($job);
$job->onMinute('35-40')->doJob("echo 'bar'");
$crontab->add($job);

// 移除任務(支援正則)
$crontab->removeJob('/echo foo/');

// 儲存寫入系統 crontab
$crontab->save();

// 取得所有任務陣列
$jobs = $crontab->getJobs();

3. 時間表達式輔助方法

方法說明範例
on($cronExpr)完整 cron 表達式on('0 2 * * *') 每天 02:00
everyMinute()每分鐘
everyHour()每小時
daily($time)每天指定時間daily('14:30')
weekly($day, $time)每週weekly(1, '09:00') 週一 09:00
monthly($date, $time)每月monthly(1, '00:00') 每月 1 號

二、方案二:Ssh2_crontab_manager(遠程伺服器管理)

適用於跳板機/管理後台集中管理多台伺服器的 crontab。

1. 環境需求

  • PHP ssh2 擴展:pecl install ssh2-1.3.1(需 libssh2-devel)
  • 目標主機開啟 SSH、允許密碼/金鑰登入
  • 管理用戶具備 crontab 權限

2. 類完整實現(精簡版)

<?php
class Ssh2CrontabManager {
    private $conn;
    private string $remoteFile = '/tmp/crontab_backup.txt';

    public function __construct(string $host, int $port, string $user, string $pass) {
        $this->conn = ssh2_connect($host, $port);
        if (!$this->conn) throw new Exception("SSH 連線失敗");
        if (!ssh2_auth_password($this->conn, $user, $pass)) throw new Exception("認證失敗");
    }

    // 執行遠程指令
    private function exec(string $cmd): string {
        $stream = ssh2_exec($this->conn, $cmd);
        stream_set_blocking($stream, true);
        return stream_get_contents($stream);
    }

    // 同步遠程 crontab 到本地暫存檔
    public function sync(): self {
        $this->exec("crontab -l > {$this->remoteFile} 2>/dev/null || > {$this->remoteFile}");
        return $this;
    }

    // 新增任務
    public function addJob(string $schedule, string $command): self {
        $line = "{$schedule} {$command}";
        $this->exec("echo '{$line}' >> {$this->remoteFile}");
        return $this;
    }

    // 移除任務(正則匹配)
    public function removeJob(string $pattern): self {
        $this->exec("grep -v -E '{$pattern}' {$this->remoteFile} > {$this->remoteFile}.new && mv {$this->remoteFile}.new {$this->remoteFile}");
        return $this;
    }

    // 寫回遠程 crontab
    public function save(): bool {
        $result = $this->exec("crontab {$this->remoteFile}");
        $this->exec("rm -f {$this->remoteFile} {$this->remoteFile}.new");
        return strpos($result, 'error') === false;
    }

    // 取得當前任務列表
    public function listJobs(): array {
        $output = $this->exec("cat {$this->remoteFile}");
        return array_filter(explode("\n", trim($output)));
    }
}

// 使用範例
$mgr = new Ssh2CrontabManager('192.168.1.10', 22, 'deploy', 'secret');
$mgr->sync()
    ->addJob('0 3 * * *', '/usr/bin/php /var/www/backup.php')
    ->addJob('*/10 * * * *', '/usr/bin/php /var/www/healthcheck.php')
    ->save();

三、安全與最佳實踐

  1. 最小權限原則:建立專用系統用戶(如 cronmgr),僅授予 crontab 權限,/etc/sudoers 限制 NOPASSWD: /usr/bin/crontab。
  2. 輸入驗證:排程表達式嚴格驗證(cron-expression 庫),指令路徑白名單,防止命令注入。
  3. 審計日誌:所有增刪改操作記錄至資料庫/日誌(操作人、時間、變更前後內容)。
  4. 冪等性設計:新增前先 removeJob 再 addJob,避免重複任務。
  5. 備份與回滾:save() 前自動備份 crontab -l > /backup/crontab_$(date +%F).bak。

四、常見問題排查

現象原因解決
save() 後任務未生效PHP-FPM 用戶無 crontab 權限將用戶加入 crontab 群組或 sudoers
SSH2 連線逾時防火牆/SELinux/SSH 配置檢查 22 port、允許 PasswordAuthentication
特殊字元導致指令失效未轉義 $、%、反引號等使用 escapeshellarg() 包裹指令參數
環境變數缺失(如 PATH)crontab 執行環境極簡指令前加 PATH=/usr/local/bin:/usr/bin && 或腳本內完整路徑

結語

PHP 管理 Crontab 透過 php-crontab-manager 可快速落地本機自動化;跨伺服器場景結合 SSH2 實現集中式管控。核心在於權限隔離、輸入驗證與操作審計。建議將管理介面整合至內部運維平台,搭配 GitOps 流程(crontab 定義存儲於 Git、CI/CD 自動同步),實現基礎設施即代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved