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

PHP 逐行讀取大型文字檔並存入陣列:記憶體優化與多種方法對比

     編輯:PHP 相關知識

基本方法:fopen + fgets 迴圈

<?php
$file = fopen('users.txt', 'r');
if (!$file) die('無法開啟檔案');

$users = [];
while (($line = fgets($file)) !== false) {
    $line = rtrim($line, "\n\r"); // 移除換行符
    if ($line !== '') {           // 略過空行
        $users[] = $line;
    }
}
fclose($file);

print_r($users);
// Array ( [0] => user01 [1] => user02 ... )
?>

進階:Generator 逐行產生(極低記憶體)

<?php
function readLines(string $filename): Generator {
    $fh = fopen($filename, 'r');
    if (!$fh) throw new RuntimeException("Cannot open $filename");
    try {
        while (($line = fgets($fh)) !== false) {
            yield rtrim($line, "\n\r");
        }
    } finally {
        fclose($fh);
    }
}

// 使用方式:逐行處理,不一次載入全部
foreach (readLines('huge_log.txt') as $line) {
    if (str_contains($line, 'ERROR')) {
        processError($line);
    }
}
// 記憶體佔用恆定,無論檔案多大
?>

常用便捷函數對比

函數行為記憶體適用場景
file($file)一次讀全檔 → 陣列(每行含換行符)高(整檔載入)小檔案、需隨機存取行號
file_get_contents($file)一次讀全檔 → 字串高需整體字串處理(正則、JSON 解析)
fgets($fh)逐行讀取低(單行緩衝)大檔案、串流處理、記憶體受限
SplFileObject物件導向逐行迭代低需面向物件、可配合 FilterIterator
Generator + fgets逐行產生極低超大檔案、管線處理、併發友善

SplFileObject 範例

<?php
$file = new SplFileObject('data.csv');
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY | SplFileObject::READ_AHEAD);

foreach ($file as $row) {
    // $row 已自動解析為陣列
    [$id, $name, $email] = $row;
    // 處理...
}
?>

編碼處理:非 UTF-8 檔案

<?php
// Big5/GBK 檔案轉 UTF-8 逐行讀取
$fh = fopen('big5.txt', 'r');
while (($line = fgets($fh)) !== false) {
    $line = iconv('BIG5', 'UTF-8//IGNORE', $line);
    // 處理 $line...
}
fclose($fh);
?>

效能測試參考(100MB 檔案,100萬行)

方法時間峰值記憶體
file()1.2s~280 MB
fgets() 迴圈0.9s~2 MB
Generator0.9s~1 MB
SplFileObject1.0s~2 MB

最佳實踐建議

  1. 檔案 < 10MB:file() 或 file_get_contents() 最簡潔
  2. 檔案 > 10MB 或記憶體受限:fgets() 迴圈或 SplFileObject
  3. 資料管線/轉換/過濾:Generator 最靈活,可串聯 array_filter、array_map 風格處理
  4. 永遠 fclose() 或用 try/finally 確保釋放檔案控制代碼
  5. CSV/TSV 結構化資料 → SplFileObject::READ_CSV 內建解析
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved