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

Yii 1.x 透過 Console Command 建立排程任務

     編輯:PHP 綜合知識

架構概覽


專案根目錄 /
├── framework/           # Yii 框架核心
├── protected/
│   ├── commands/
│   │   ├── cron.php          # 入口腳本
│   │   └── ShellCommand.php  # 實際命令類別
│   ├── config/
│   │   ├── console.php       # Console 專用設定
│   │   └── main.php          # Web 共用設定
│   └── ...
└── public/
    └── index.php

步驟 1:建立 Console 入口腳本

protected/commands/cron.php

<?php
// 修改為實際框架路徑
$yii = dirname(__FILE__) . '/../../framework/yii.php';

require_once($yii);

$configFile = dirname(__FILE__) . '/../config/console.php';

Yii::createConsoleApplication($configFile)->run();

步驟 2:Console 專用設定檔

protected/config/console.php

<?php
return [
    'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..',
    'name' => 'Console App',

    // 預載入模型、元件、擴充套件
    'import' => [
        'application.models.*',
        'application.components.*',
        'application.extensions.*',
    ],

    'components' => [
        // Log 設定:寫入檔案而非網頁
        'log' => [
            'class' => 'CLogRouter',
            'routes' => [
                [
                    'class' => 'CFileLogRoute',
                    'levels' => 'info, warning, error',
                    'logFile' => 'console.log',
                ],
            ],
        ],

        // 資料庫連線 (可與 Web 共用或獨立)
        'db' => [
            'class' => 'CDbConnection',
            'connectionString' => 'mysql:host=localhost;dbname=myapp',
            'username' => 'user',
            'password' => 'pass',
            'charset' => 'utf8',
            'tablePrefix' => 'tbl_',
            'emulatePrepare' => true,
        ],

        // 如需快取、郵件等元件亦可在此設定
    ],

    'params' => require('params.php'),
];

步驟 3:建立命令類別

protected/commands/ShellCommand.php

<?php
class ShellCommand extends CConsoleCommand
{
    // 定義動作:php cron.php shell sendReport
    public function actionSendReport($args = [])
    {
        $this->stdout("開始發送日報...\n");

        // 使用模型、元件如同 Web 環境
        $users = User::model()->findAll('status=1');
        foreach ($users as $user) {
            // 發送邏輯...
            $this->stdout("處理用戶: {$user->email}\n");
        }

        $this->stdout("日報發送完成\n");
        return 0; // 正常結束代碼
    }

    // 另一個動作:php cron.php shell cleanup
    public function actionCleanup($days = 30)
    {
        $this->stdout("清理 {$days} 天前的暫存資料...\n");
        $count = TempFile::model()->deleteAll('created_at < :date', [
            ':date' => date('Y-m-d', strtotime("-{$days} days"))
        ]);
        $this->stdout("已刪除 {$count} 筆\n");
        return 0;
    }

    // 覆寫 getHelp() 提供說明
    public function getHelp()
    {
        return << [params]

可用動作:
  sendReport    發送每日報表
  cleanup [days]  清理暫存檔 (預設 30 天)

HELP;
    }
}

步驟 4:註冊命令 (自動發現)

Yii 1.x 會自動掃描 protected/commands/ 下的 *Command.php,類別名稱對應命令名稱:

  • ShellCommand → shell
  • BackupCommand → backup

步驟 5:設定 Crontab

# 編輯 crontab
crontab -e

# 範例:每天凌晨 2:30 執行日報發送
30 2 * * * /usr/bin/php /var/www/project/protected/commands/cron.php shell sendReport >> /var/log/cron_sendReport.log 2>&1

# 每小時清理暫存
0 * * * * /usr/bin/php /var/www/project/protected/commands/cron.php shell cleanup 7 >> /var/log/cron_cleanup.log 2>&1

# 每週日 3:00 備份資料庫
0 3 * * 0 /usr/bin/php /var/www/project/protected/commands/cron.php backup >> /var/log/cron_backup.log 2>&1

重要注意事項

項目說明
PHP CLI 版本確保 /usr/bin/php 為正確版本 (可用 php -v 驗證)
環境變數CLI 不載入 Web 環境變數,需在 console.php 完整設定 DB、路徑等
執行權限cron 執行者需有專案目錄讀取權限、log 寫入權限
記憶體限制CLI 獨立 php.ini,大量資料處理請調整 memory_limit
避免重複執行長時間任務加鎖 (flock/Redis lock) 防止重疊
錯誤通知導向 log 檔,並設定 logrotate;關鍵失敗發送郵件/Slack

進階:加鎖防止重複執行

<?php
class ShellCommand extends CConsoleCommand
{
    public function actionSendReport()
    {
        $lockFile = sys_get_temp_dir() . '/cron_sendReport.lock';
        $fp = fopen($lockFile, 'w');

        if (!flock($fp, LOCK_EX | LOCK_NB)) {
            $this->stderr("上一任務尚未結束,跳過本次執行\n");
            return 1;
        }

        try {
            // 實際任務邏輯...
        } finally {
            flock($fp, LOCK_UN);
            fclose($fp);
        }
        return 0;
    }
}
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved