<?php
// 設定最大執行時間為 2400 秒 (40 分鐘)
ini_set('max_execution_time', 2400);
// 設定記憶體上限為 1 GB (1048576000 bytes)
// 注意:若 php.ini 設定 memory_limit = -1 (無限制),此設定無效
ini_set('memory_limit', '1048576000'); // 或 '1G' (PHP 5.2+ 支援簡寫)
// 立即生效驗證
echo 'max_execution_time: ' . ini_get('max_execution_time') . " 秒\n";
echo 'memory_limit: ' . ini_get('memory_limit') . "\n";
?>
| 限制 | 說明 |
|---|---|
| 僅限當前腳本 | 不影響其他請求、CLI 指令、全域設定。 |
| 安全模式 / suhosin | 舊版 PHP 安全模式或 Suhosin 硬化補丁可能禁止修改此兩項。 |
| Web 伺服器逾時 | Nginx fastcgi_read_timeout、Apache Timeout、Proxy proxy_read_timeout 可能先於 PHP 逾時切斷連線。 |
| CLI 無時間限制預設 | CLI SAPI 預設 max_execution_time = 0 (無限制),通常無需修改。 |
| 記憶體設定上限 | 受限於系統實體記憶體、ulimit -v、容器 memory.limit_in_bytes。 |
與其無限拉長單一腳本,建議採用 分批 + 排程 架構:
<?php
// 範例:每批處理 500 筆,透過 CLI 排程 (cron) 每分鐘執行
$batchSize = 500;
$offset = (int)($argv[1] ?? 0);
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare('SELECT id, data FROM big_table WHERE processed = 0 LIMIT :offset, :limit');
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':limit', $batchSize, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($rows)) {
echo "處理完成\n";
exit(0);
}
foreach ($rows as $row) {
// 處理單筆
processItem($row);
// 標記完成
$pdo->prepare('UPDATE big_table SET processed = 1 WHERE id = ?')->execute([$row['id']]);
}
echo "已處理 {$offset} - " . ($offset + count($rows)) . "\n";
// 下一批由 cron 呼叫: php batch.php " . ($offset + $batchSize)
?>
優點:記憶體穩定、可中斷恢復、並行處理、不受單一請求逾時限制。
memory_get_peak_usage(true) 記錄峰值。set_time_limit(0) (CLI) 或具體秒數時,搭配 ignore_user_abort(true) 防止用戶關閉瀏覽器中斷。