Yii 提供 CConsoleCommand 讓你以 CLI 方式執行背景任務:資料同步、報表產生、郵件佇列發送、清理過期資料等。本文完整涵蓋獨立配置檔、命令類別建立、執行方式、參數處理、排程整合五大面向。
建立 protected/config/console.php,與 Web 端 main.php 分離,避免載入不必要元件。
dirname(__FILE__) . DIRECTORY_SEPARATOR . '..',
'name' => 'My Console Application',
// 自動載入模型、元件、擴充
'import' => array(
'application.models.*',
'application.components.*',
'application.extensions.*',
),
'components' => array(
// 資料庫連線(與 Web 端共用或獨立)
'db' => array(
'connectionString' => 'mysql:host=localhost;dbname=myapp',
'username' => 'console_user',
'password' => 'secret',
'charset' => 'utf8',
'tablePrefix' => 'tbl_',
'enableProfiling' => true,
'enableParamLogging' => true,
),
// 郵件元件(背景發送常用)
'mailer' => array(
'class' => 'application.extensions.mailer.EMailer',
),
// 快取(可選)
'cache' => array('class' => 'CFileCache'),
// 日誌輸出到檔案
'log' => array(
'class' => 'CLogRouter',
'routes' => array(
array('class' => 'CFileLogRoute', 'levels' => 'error, warning, info', 'logFile' => 'console.log'),
),
),
),
);
放置於 protected/commands/,命名規則:TaskNameCommand.php,類別繼承 CConsoleCommand。
addOption('batchSize', 'b', '每批處理筆數', '100');
$options = $parser->parse($args);
$this->batchSize = (int)$options['batchSize'];
echo "開始同步作業,批次大小:{$this->batchSize}\n";
$this->processSync();
echo "同步完成\n";
}
private function processSync() {
$offset = 0;
while (true) {
$items = ExternalApi::fetchBatch($offset, $this->batchSize);
if (empty($items)) break;
foreach ($items as $item) {
LocalModel::syncFromApi($item);
}
$offset += $this->batchSize;
echo "已處理 {$offset} 筆...\n";
sleep(1); // 禮貌性延遲
}
}
}
# 進入 protected 目錄 cd /var/www/myapp/protected # 列出所有可用命令 php yiic.php # 執行 sync 命令 php yiic.php sync --batchSize=200 # 直接執行動作(若命令類別有 actionX 方法) php yiic.php sync run --batchSize=50
if (!$this->confirm("確定要刪除所有暫存資料嗎?")) {
echo "已取消\n";
return;
}
$total = count($items);
$bar = new CConsoleProgressBar($total);
foreach ($items as $i => $item) {
$this->processItem($item);
$bar->update($i + 1);
}
$bar->finish();
echo "\033[32m成功\033[0m\n"; // 綠色 echo "\033[31m失敗\033[0m\n"; // 紅色 echo "\033[33m警告\033[0m\n"; // 黃色
// 需在 console.php 匯入 urlManager
$url = Yii::app()->urlManager->createAbsoluteUrl('post/view', array('id' => 1));
# 編輯 crontab crontab -e # 每天凌晨 2:00 執行同步 0 2 * * * /usr/bin/php /var/www/myapp/protected/yiic.php sync --batchSize=500 >> /var/log/sync.log 2>&1 # 每小時執行郵件佇列發送 0 * * * * /usr/bin/php /var/www/myapp/protected/yiic.php mailQueue send >> /var/log/mail.log 2>&1 # 每週日清理過期 Session 0 3 * * 0 /usr/bin/php /var/www/myapp/protected/yiic.php gc session >> /var/log/gc.log 2>&1
適用於佇列消費者、WebSocket 伺服器等需持續運行的任務。
; /etc/supervisor/conf.d/queue_worker.conf [program:queue_worker] command=/usr/bin/php /var/www/myapp/protected/yiic.php queue listen --timeout=60 directory=/var/www/myapp/protected user=www-data autostart=true autorestart=true stdout_logfile=/var/log/queue_worker.log redirect_stderr=true numprocs=2
Yii Console Command 讓 PHP 邁入系統級自動化領域。關鍵在於:分離 console.php 配置、善用 getHelp() 文檔化、搭配 Supervisor/Crontab 達成生產級排程。建議專案建立 commands/ 目錄規範,所有背景任務統一納入管理。