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

PHP 讀取檔案完全指南:file_get_contents、fread、file、串流與大檔案處理策略

     編輯:PHP 相關知識

PHP 讀取檔案的四種核心方式

根據檔案大小、記憶體限制、處理需求選擇最適合的讀取方法。

方式一:file_get_contents(最常用、全讀入記憶體)

<?php
$file = 'filelist.php';

// 1. 檢查可讀性
if (!is_readable($file)) {
    die("檔案不存在或不可讀: $file");
}

// 2. 一次性讀取全部內容
$data = file_get_contents($file);
if ($data === false) die("讀取失敗");

// 3. 輸出(注意編碼)
echo htmlentities($data);
?>
  • 優點:簡潔、效能好(內部使用映射檔案/串流優化)。
  • 限制:受 memory_limit 限制,不適合超大檔案(> 100MB)。
  • 支援遠程 URL:需開啟 allow_url_fopen。

方式二:fopen/fread/fclose(精細控制、分塊讀取)

<?php
$file = 'large.log';
$handle = fopen($file, 'rb');
if (!$handle) die("無法開啟");

$chunkSize = 8192; // 8KB 緩衝
while (!feof($handle)) {
    $chunk = fread($handle, $chunkSize);
    if ($chunk === false) { fclose($handle); die("讀取錯誤"); }
    // 處理 chunk(輸出、解析、寫入另一檔案...)
    echo $chunk;
}
fclose($handle);
?>
  • 適用於大檔案、二進制檔案、記憶體受限環境。
  • 可配合 fseek 隨機存取。

方式三:file() 讀取為陣列(逐行處理)

<?php
$file = 'data.txt';
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines === false) die("讀取失敗");

foreach ($lines as $lineNum => $line) {
    echo "第 $lineNum 行: $line\n";
}

// 反轉順序
$reversed = array_reverse($lines);
?>
  • 自動按換行符分割成陣列,支援旗標 FILE_IGNORE_NEW_LINES、FILE_SKIP_EMPTY_LINES。
  • 同樣全量載入記憶體,大檔案慎用。

方式四:SplFileObject(物件導向、可迭代、記憶體友善)

<?php
$file = new SplFileObject('large.csv', 'r');
$file->setFlags(
    SplFileObject::READ_CSV |      // 自動解析 CSV
    SplFileObject::READ_AHEAD |    // 預讀
    SplFileObject::SKIP_EMPTY |    // 跳過空行
    SplFileObject::DROP_NEW_LINE   // 移除換行符
);

foreach ($file as $rowNum => $fields) {
    // $fields 已是陣列
    echo "Row $rowNum: " . implode(', ', $fields) . "\n";
}
// 自動關閉檔案
?>
  • 實作 Iterator,支援 foreach、seek()、current()、fgetcsv() 等豐富方法。
  • 延遲載入,僅在迭代時讀取當前行,適合大檔案。

二進制檔案讀取技巧

<?php
// 方法 1: fread + unpack
$handle = fopen('image.png', 'rb');
$header = fread($handle, 8); // PNG 簽名 8 位元組
$sig = unpack('C8', $header);
fclose($handle);

// 方法 2: file_get_contents + unpack(小檔案)
$data = file_get_contents('image.png');
$sig = unpack('C8', substr($data, 0, 8));

// 方法 3: 串流過濾器(即時處理)
$handle = fopen('data.bin', 'rb');
stream_filter_append($handle, 'convert.base64-encode');
$base64 = stream_get_contents($handle);
fclose($handle);
?>

效能與記憶體對比

方式記憶體佔用適用檔案大小隨機存取CSV/結構化解析
file_get_contentsO(檔案大小)< 50MB否需自行分割
file()O(檔案大小) + 陣列開銷< 20MB否逐行自行解析
fopen/freadO(緩衝區)無限制是需自行實作
SplFileObjectO(單行)無限制是內建 READ_CSV

最佳實踐清單

  1. 小檔案(配置、模板、靜態資源):file_get_contents。
  2. 大檔案/日誌/匯出資料:SplFileObject 或 fopen/fread 分塊處理。
  3. CSV/TSV 結構化資料:SplFileObject::READ_CSV。
  4. 遠程資源:file_get_contents(簡單)或 Guzzle 串流(健壯)。
  5. 編碼處理:讀取後統一 mb_convert_encoding($data, 'UTF-8', 'auto') 或指定 fopen($file, 'r', false, stream_context_create(['encoding'=>'UTF-8']))。
  6. 錯誤處理:統一檢查回傳值 === false,拋出具體異常而非 die()。

總結

現代 PHP 專案應以 SplFileObject 為首選檔案讀取介面,兼具 OOP 風格、記憶體效率、豐富功能。file_get_contents 適合簡單小檔案,fopen/fread 保留給極致效能調優或特殊二進制處理。統一封裝 FileReader 服務,屏蔽底層差異,提供 readAll()、readLines()、readCsv()、streamCopyTo() 等高層 API,是專案可維護性的關鍵。

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