函式對比
| 函式 | 回傳值 | 適用場景 |
file() | 陣列,每行為一元素(含換行符) | 需逐行處理、統計行數、隨機存取某行 |
readfile() | 直接輸出到輸出緩衝區,回傳位元組數 | 單純輸出檔案內容(如圖片、下載) |
fopen()/fgets() | 資源控制代碼,手動控制讀取指標 | 大檔案串流、需精細控制讀取邏輯 |
實作步驟
1. 準備測試檔案 data.txt
第一行內容
第二行內容
第三行內容
2. 核心代碼
<?php
// 1. 讀取整個檔案到陣列
$myFile = file("data.txt"); // $myFile[0] = "第一行內容\n"
// 2. 遍歷陣列輸出
$lineCount = count($myFile);
for ($index = 0; $index < $lineCount; $index++) {
// 移除行尾換行符並加上 HTML 換行
echo rtrim($myFile[$index]) . "<br>";
}
?>
3. 完整 HTML 範例
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>讀取文字檔案</title></head><body>
<?php
$filePath = "data.txt";
if (!file_exists($filePath)) {
die("檔案不存在: $filePath");
}
$lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// FILE_IGNORE_NEW_LINES: 移除每行末尾換行符
// FILE_SKIP_EMPTY_LINES: 跳過空行
foreach ($lines as $lineNum => $content) {
echo "第 " . ($lineNum + 1) . " 行: " . htmlspecialchars($content) . "<br>";
}
?>
</body></html>
進階技巧
- 大檔案分塊讀取:
fopen() + fgets() 迴圈,避免一次載入全部記憶體
- CSV 解析:
fgetcsv() 自動處理欄位分隔、引號轉義
- 檔案鎖定:
flock($fp, LOCK_SH) 共享鎖讀取、LOCK_EX 獨佔鎖寫入
- 編碼轉換:
mb_convert_encoding($line, 'UTF-8', 'BIG5') 處理舊系統編碼
- SplFileObject:物件導向介面,支援
seek()、current()、key() 等迭代器方法
常見錯誤與解決
| 錯誤 | 原因 | 解決 |
| Permission denied | 檔案/目錄權限不足 | chmod 644 檔案、755 目錄;確認 PHP 執行身分權限 |
| No such file or directory | 相對路徑錯誤 | 使用 __DIR__ . '/data.txt' 絕對路徑 |
| Memory exhausted | 大檔案用 file() 吃光記憶體 | 改用 fgets() 逐行讀取 |
| 亂碼 | 檔案編碼與腳本編碼不符 | 統一 UTF-8 或用 mb_convert_encoding 轉碼 |
總結
file() 是 PHP 讀取中小型文字檔案最便捷的函式,自動將內容轉為陣列便於遍歷。搭配 FILE_IGNORE_NEW_LINES、FILE_SKIP_EMPTY_LINES 旗標可直接獲得乾淨的資料陣列。大檔案或需串流處理時,請改用 fopen()/fgets() 或 SplFileObject。