根據檔案大小、記憶體限制、處理需求選擇最適合的讀取方法。
<?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)。allow_url_fopen。<?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 隨機存取。<?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。<?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_contents | O(檔案大小) | < 50MB | 否 | 需自行分割 |
| file() | O(檔案大小) + 陣列開銷 | < 20MB | 否 | 逐行自行解析 |
| fopen/fread | O(緩衝區) | 無限制 | 是 | 需自行實作 |
| SplFileObject | O(單行) | 無限制 | 是 | 內建 READ_CSV |
file_get_contents。SplFileObject 或 fopen/fread 分塊處理。SplFileObject::READ_CSV。file_get_contents(簡單)或 Guzzle 串流(健壯)。mb_convert_encoding($data, 'UTF-8', 'auto') 或指定 fopen($file, 'r', false, stream_context_create(['encoding'=>'UTF-8']))。=== false,拋出具體異常而非 die()。現代 PHP 專案應以 SplFileObject 為首選檔案讀取介面,兼具 OOP 風格、記憶體效率、豐富功能。file_get_contents 適合簡單小檔案,fopen/fread 保留給極致效能調優或特殊二進制處理。統一封裝 FileReader 服務,屏蔽底層差異,提供 readAll()、readLines()、readCsv()、streamCopyTo() 等高層 API,是專案可維護性的關鍵。