PHP 默認 max_execution_time = 30 秒,處理 5,000 條記錄僅能跑 700 條。面對 10 萬+ 數據量,必須突破時間限制。本文對比三種方案優劣,助你選型。
最直接但風險最高。
<?php
ini_set('max_execution_time', '100'); // 100 秒
// 或
ini_set('max_execution_time', '0'); // 0 代表無限制(注意:Zend Server 下 0 約等於 120s,需設極大值)
優點:零代碼改動,立竿見影。
缺點:長連接佔用 FPM 進程,併發能力驟降;Apache/Nginx 仍有自身超時(如 FastCgiReadTimeout、proxy_read_timeout)需同步調大;記憶體洩漏風險放大。
利用 php.exe 以 CLI 模式運行腳本,完全脫離 Web 服務器超時限制,適合定時任務、數據遷移、報表生成。
run_task.bat@REM<?php
@REM =='
@SET PHPCLI="D:\Program Files\Zend\Zend Studio - 8.0.1\plugins\org.zend.php.debug.debugger.win32.x86_5.3.18.v20110322\resources\php53\php.exe"
@REM PHPCLI 設置你的 php.exe 絕對路徑
@%PHPCLI% %0
@goto :EOF
@REM';?>
<?php
include 'C:\\Program Files\\Zend\\Apache2\\htdocs\\pic_gather\\pic_operate.php';
echo "\rfinish";
ob_flush();
exec("pause");
?>
@SET PHPCLI=... 設定 PHP CLI 可執行文件路徑。@%PHPCLI% %0 以 PHP 解釋器運行**自身**(.bat 文件)。@REM 視為字符串 '@REM ==',@ 抑制錯誤,== 比較無副作用,安全通過。@goto :EOF 讓批處理引擎直接跳到文件末尾,**不再解析後續 PHP 代碼**,避免 CMD 窗口輸出垃圾文本。include 真正業務邏輯,結束後 exec("pause") 保持窗口查看結果。優點:無超時限制、不佔用 Web Worker、可納入 Windows 任務計劃程式定時執行。
缺點:僅限 Windows 環境;需維護 .bat 模板。
若業務僅是字符串拼接、字段衍生(如 class='自然風光' → image 路徑加前綴),**完全不需要 PHP 迴圈**,單條 UPDATE 即可:
UPDATE `images`
SET `path` = CONCAT('pic_gather/nature/', `path`)
WHERE `class` = '自然風光';
MySQL CONCAT()、REPLACE()、SUBSTRING() 等函數足以覆蓋 80% 字符串處理需求,效率比 PHP 迴圈高數量級。
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 一次性數據修復、報表導出、需複雜邏輯(圖片處理、API 調用) | 方案二 | 脫離 Web 容器,穩定可控,支援長時間運行 |
| 簡單字段更新、數據清洗、批量導入 | 方案三 | 資料庫層面完成,無網絡開銷,秒級處理百萬行 |
| 臨時測試、數據量 < 1 萬、無法訪問服務器 Shell | 方案一 | 改動最小,但需同步調整 Nginx/Apache 超時 |
生產環境多為 Linux,請直接編寫純 PHP CLI 腳本 + Crontab/Systemd Timer:
#!/usr/bin/env php
<?php
// cli_task.php
ini_set('memory_limit', '512M');
set_time_limit(0); // CLI 模式下 0 真正無限制
require_once __DIR__ . '/bootstrap.php';
// 業務邏輯...
# crontab -e
0 2 * * * /usr/bin/php /var/www/cli_task.php >> /var/log/cli_task.log 2>&1
CLI 模式無 Web 服務器干擾,配合 pcntl_fork 多進程、Redis/RabbitMQ 佇列,可構建企業級異步任務系統。