$argc:參數個數(包含腳本名稱),整數$argv:參數陣列,$argv[0] 為腳本路徑,$argv[1] 為第一個實際參數<?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 資料。
# 每 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
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) {
// 業務邏輯...
}
?>
<?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";
?>
php_sapi_name() === 'cli',防止 Web 誤執行$argv[1] ?? 'default' 提供預設值getopt() 或 symfony/console、laravel/consoleexit(0) 成功、exit(1) 參數錯誤、exit(2) 業務失敗memory_limit,大任務可 ini_set('memory_limit', '512M'):: 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