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

PHP argc/argv 命令列參數完整解析:定時任務多進程並行實戰

     編輯:PHP 綜合知識

核心概念

  • $argc:參數個數(包含腳本名稱),整數
  • $argv:參數陣列,$argv[0] 為腳本路徑,$argv[1] 為第一個實際參數
  • 僅在 CLI 模式 可用(Web 模式下未定義)

基本用法

<?php
// test.php
echo "argc = $argc\n";
echo "argv = " . print_r($argv, true) . "\n";

// 執行:php test.php arg1 arg2 "arg with space"
// 輸出:
// argc = 4
// argv = Array
// (
//     [0] => test.php
//     [1] => arg1
//     [2] => arg2
//     [3] => arg with space
// )
?>

實戰場景:定時任務多進程分片處理

需求:每 30 分鐘處理大量資料,單進程太慢,啟動 3 進程並行,各處理 1/3 資料。

crontab 設定

# 每 30 分鐘啟動 3 個進程,參數 1/2/3 代表分片編號
*/30 * * * * /usr/local/bin/php /var/www/html/cron/process_data.php 1 >> /var/log/process_1.log 2>&1
*/30 * * * * /usr/local/bin/php /var/www/html/cron/process_data.php 2 >> /var/log/process_2.log 2>&1
*/30 * * * * /usr/local/bin/php /var/www/html/cron/process_data.php 3 >> /var/log/process_3.log 2>&1

PHP 腳本 process_data.php

<?php
// 1. 取得分片參數
$shardId = $argv[1] ?? 1; // 預設分片 1
$totalShards = 3;

// 2. 參數驗證
if (!in_array($shardId, range(1, $totalShards))) {
    fwrite(STDERR, "Error: shard_id must be 1-$totalShards\n");
    exit(1);
}

// 3. 計算分片範圍(假設處理 ID 1-10000)
$totalRecords = 10000;
$perShard = (int)ceil($totalRecords / $totalShards);
$startId = ($shardId - 1) * $perShard + 1;
$endId = min($shardId * $perShard, $totalRecords);

echo "[$shardId/$totalShards] Processing ID $startId - $endId\n";

// 4. 實際業務邏輯
$db = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $db->prepare("SELECT * FROM big_table WHERE id BETWEEN ? AND ?");
$stmt->execute([$startId, $endId]);

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // 處理單筆資料...
    processRecord($row);
}

echo "Shard $shardId completed.\n";

function processRecord($row) {
    // 業務邏輯...
}
?>

進階:getopt() 解析複雜參數

<?php
// 支援短選項 -f -v 和長選項 --file --verbose
$options = getopt("f:v::", ["file:", "verbose::", "help"]);

/*
執行:php script.php -f data.txt --verbose --dry-run
$options = [
    'f' => 'data.txt',
    'verbose' => '',        // 無值時為空字串
    'help' => false,        // 無值長選項為 false
]
*/

$file = $options['f'] ?? $options['file'] ?? 'default.txt';
$verbose = isset($options['v']) || isset($options['verbose']);
$dryRun = isset($options['dry-run']);

echo "File: $file\n";
echo "Verbose: " . ($verbose ? 'on' : 'off') . "\n";
echo "Dry-run: " . ($dryRun ? 'yes' : 'no') . "\n";
?>

最佳實踐檢查清單

  1. ☑ 腳本開頭檢查 php_sapi_name() === 'cli',防止 Web 誤執行
  2. ☑ 使用 $argv[1] ?? 'default' 提供預設值
  3. ☑ 複雜參數用 getopt() 或 symfony/console、laravel/console
  4. ☑ 進程間避免資源競爭(資料庫鎖、檔案鎖、Redis 分散式鎖)
  5. ☑ 日誌分離:每進程獨立日誌檔,便於排查
  6. ☑ 退出碼規範:exit(0) 成功、exit(1) 參數錯誤、exit(2) 業務失敗
  7. ☑ 記憶體限制:CLI 獨立 memory_limit,大任務可 ini_set('memory_limit', '512M')

Windows 批次檔包裝(方便排程)

:: run_process.bat
@echo off
set PHP_PATH=C:\php\php.exe
set SCRIPT_PATH=C:\www\cron\process_data.php

:: 依序啟動 3 進程(或用 start /b 並行)
start /b %PHP_PATH% %SCRIPT_PATH% 1
start /b %PHP_PATH% %SCRIPT_PATH% 2
start /b %PHP_PATH% %SCRIPT_PATH% 3
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved