需導入約 5 萬條、5MB 的 CSV 數據。初期嘗試「上傳 → 讀取 → 入庫」一體化流程,卻接連踩坑:上傳等待體驗差、AJAX 請求 1 分鐘超時、單條插入性能低、continue 導致莫名 500 錯誤。
import/ 目錄,返回文件名。排查過程:
max_execution_time = 300 無效ini_set('max_input_time', 300),ini_get 仍返回 60php.ini 重啟 Apache 後仍超時根因: 可能受 Web 服務器(Apache/Nginx)或代理層的 Timeout/proxy_read_timeout 限制。
終極方案 —— 分批異步處理:
{status: 'continue', processed: 2000}status === 'done'continue 陷阱循環中使用 continue 跳過已存在記錄時,約在 8000 條報「Internal Server Error」。改用 if-else 結構後問題消失。推測與 GC 或內存峰值有關,具體原因待深究。
-- 慢:逐條執行 INSERT INTO t (a,b) VALUES (1,2); INSERT INTO t (a,b) VALUES (3,4); -- 快:單語句多值 INSERT INTO t (a,b) VALUES (1,2), (3,4), ...;
SplFileObject 內建指針控制,適合大文件隨機讀取,無需一次性載入內存。
function getFileLines($filename, $startLine, $endLine, $method = 'rb') {
$content = [];
$filename = DATA_PATH . DS . 'import' . DS . $filename;
$count = $endLine - $startLine;
$fp = new SplFileObject($filename, $method);
$fp->seek($startLine); // 從 0 開始計數
for ($i = 0; $i <= $count; ++$i) {
$content[] = $fp->current();
$fp->next();
}
return array_filter($content); // 過濾空行
}
fgetcsv 更靈活,支持 seek() 隨機訪問。continue 異常,優先嘗試 if-else 重構。若您知道 continue 導致 500 錯誤的深層原因,或有更優雅的超時突破方案,歡迎留言交流!