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

PHP 讀取檔案內容到陣列:file() 函數用法與大檔案替代方案

     編輯:PHP 相關知識

file() 函數基本特性

file(string $filename, int $flags = 0, ?resource $context = null): array|false 將整個檔案讀入陣列,每行為一個元素,保留換行符。適合小型檔案,大檔案會耗盡記憶體。

基本範例

<?php
$lines = file('/tmp/file.txt');
if ($lines === false) {
    die('讀取失敗');
}

foreach ($lines as $lineNum => $line) {
    // 移除尾部換行符(file() 保留 \n 或 \r\n)
    $clean = rtrim($line, "\r\n");
    echo "Line {$lineNum}: {$clean}\n";
}
?>

常用 Flags 參數

FILE_IGNORE_NEW_LINESFILE_SKIP_EMPTY_LINESFILE_TEXT
Flag效果
自動移除每行尾部換行符(推薦)
跳過空白行
以文字模式讀取(Windows 影響換行轉換)

推薦寫法:組合 Flags

<?php
// 一次搞定:去換行符 + 跳過空行
$lines = file('/tmp/file.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

foreach ($lines as $line) {
    // $line 已經是乾淨的字串
    processLine($line);
}
?>

記憶體效能陷阱

<?php
// ⚠️ 危險:100MB 檔案會佔用 100MB+ 記憶體
$lines = file('/var/log/huge.log'); // 可能觸發 memory_limit

// ✅ 正確:逐行處理,記憶體 O(1)
$handle = fopen('/var/log/huge.log', 'r');
while (($line = fgets($handle)) !== false) {
    processLine(rtrim($line, "\r\n"));
}
fclose($handle);
?>

大檔案分塊讀取工具函數

<?php
/**
 * 逐行讀取大檔案,支援回呼處理
 * @param string $path
 * @param callable $callback function(string $line, int $lineNum): bool|void 回傳 false 中斷
 * @param int $bufferSize 緩衝區大小
 */
function readLargeFile(string $path, callable $callback, int $bufferSize = 8192): void {
    $handle = fopen($path, 'r');
    if (!$handle) throw new RuntimeException("無法開啟: {$path}");
    
    $lineNum = 0;
    try {
        while (($line = fgets($handle, $bufferSize)) !== false) {
            $line = rtrim($line, "\r\n");
            if ($callback($line, ++$lineNum) === false) {
                break; // 允許提前終止
            }
        }
    } finally {
        fclose($handle);
    }
}

// 使用範例:只找前 10 個錯誤行
$errors = [];
readLargeFile('/var/log/app.log', function($line, $num) use (&$errors) {
    if (str_contains($line, 'ERROR')) {
        $errors[] = "Line {$num}: {$line}";
        if (count($errors) >= 10) return false; // 找夠就停
    }
});
print_r($errors);
?>

CSV 專用讀取

<?php
// 使用 SplFileObject 內建 CSV 解析
$csv = new SplFileObject('data.csv', 'r');
$csv->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);

foreach ($csv as $row) {
    // $row 已是陣列:['欄位1', '欄位2', ...]
    echo implode(' | ', $row) . "\n";
}
?>

遠端檔案讀取(需 allow_url_fopen=On)

<?php
// 讀取遠端文字檔
$lines = @file('https://example.com/robots.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines !== false) {
    foreach ($lines as $line) {
        echo "{$line}\n";
    }
} else {
    echo "遠端讀取失敗";
}
?>

效能比較總結

方法記憶體速度適用場景
file()O(N)快(單次系統呼叫)< 10MB 文字檔、設定檔、小資料集
fgets() 迴圈O(1)中大檔案、日誌、串流處理
SplFileObjectO(1)中物件導向、CSV、需隨機存取行號
stream_get_contents()O(N)最快需整份字串、小檔案

根據檔案大小與處理需求選擇正確工具,file() 方便但有體積上限,大檔案必須改用串流式讀取。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved