PHP 提供多種檔案讀取函式,各有適用場景與效能特性。本文系統整理 8 種核心方法,從底層資源操作到高階便利函式,附上效能基準、記憶體特性與選擇決策樹。
| 函式 | 層級 | 回傳型別 | 記憶體模式 | 適用場景 | 二進位安全 |
|---|---|---|---|---|---|
fread() | 資源 | string | 指定長度 | 二進位檔、網路流、精確控制 | ✅ (需 rb 模式) |
fgets() | 資源 | string | 逐行 | 文字檔逐行處理、大檔案流式 | ✅ (PHP 4.3+) |
fgetss() | 資源 | string | 逐行 | 移除 HTML/PHP 標籤的文字處理 | ✅ |
file() | 高階 | array | 全量載入 | 小型設定檔、逐行陣列操作 | ✅ |
readfile() | 高階 | int (bytes) | 直接輸出 | 檔案下載、圖片輸出、無需處理內容 | ✅ |
file_get_contents() | 高階 | string | 全量載入 | 小~中檔案讀入變數、HTTP 請求 | ✅ |
fpassthru() | 資源 | int (bytes) | 直接輸出 | 已開啟資源的剩餘內容直接輸出 | ✅ |
parse_ini_file() | 專用 | array | 全量載入 | INI 設定檔解析 | N/A |
// 讀取整個檔案 (小檔案)
$handle = fopen('data.bin', 'rb');
$content = fread($handle, filesize('data.bin'));
fclose($handle);
// 遠端/流式檔案 (不可用 filesize)
$handle = fopen('https://example.com/large.file', 'rb');
$content = '';
while (!feof($handle)) {
$content .= fread($handle, 8192); // 8KB 區塊
}
fclose($handle);
// 讀取特定位移 (隨機存取)
$handle = fopen('database.idx', 'rb');
fseek($handle, 1024 * 100); // 第 100 筆記錄
$record = fread($handle, 1024);
fclose($handle);
$handle = fopen('large.log', 'r');
while (($line = fgets($handle, 4096)) !== false) {
// 處理單行,記憶體常數級
if (str_contains($line, 'ERROR')) {
error_log($line);
}
}
fclose($handle);
// fgetss() 移除標籤 (已棄用 PHP 8.0+)
$handle = fopen('template.html', 'r');
while (($line = fgetss($handle, 1024, '
')) !== false) {
echo $line; // 保留
,移除其他標籤
}
fclose($handle);
$lines = file('config.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// FILE_IGNORE_NEW_LINES: 移除換行符
// FILE_SKIP_EMPTY_LINES: 跳過空行
foreach ($lines as $i => $line) {
echo "Line {$i}: {$line}\n";
}
// 圖片/檔案下載輸出
header('Content-Type: image/jpeg');
header('Content-Disposition: attachment; filename="photo.jpg"');
header('Content-Length: ' . filesize('photo.jpg'));
readfile('photo.jpg'); // 直接輸出到瀏覽器,不佔 PHP 記憶體
exit;
// 本地檔案
$content = file_get_contents('data.json');
$data = json_decode($content, true);
// HTTP 請求 (含超時、Header、POST)
$ctx = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\nAuthorization: Bearer {$token}",
'content' => json_encode($payload),
'timeout' => 10,
],
'ssl' => [
'verify_peer' => false, // 開發環境
]
]);
$response = file_get_contents('https://api.example.com/endpoint', false, $ctx);
$handle = fopen('video.mp4', 'rb');
fseek($handle, 1024 * 1024); // 跳過前 1MB
fpassthru($handle); // 輸出剩餘內容到瀏覽器
fclose($handle);
// config.ini
; 註解
[database]
host = "127.0.0.1"
port = 3306
debug = true
[cache]
driver = "redis"
ttl = 3600
// PHP 解析
$config = parse_ini_file('config.ini', true); // true = 多維陣列保留 section
/*
[
'database' => ['host'=>'127.0.0.1', 'port'=>3306, 'debug'=>1],
'cache' => ['driver'=>'redis', 'ttl'=>3600]
]
*/
file_get_contents() : 0.12 秒 (最快,內部優化) fread() 8KB 區塊 : 0.15 秒 fgets() 4KB 逐行 : 0.18 秒 file() 陣列載入 : 0.35 秒 (記憶體峰值 200MB+) readfile() 直接輸出 : 0.10 秒 (不經 PHP 記憶體,最省資源)
需求:讀取檔案
├─ 直接輸出到瀏覽器 (下載/圖片/影片)
│ └─ readfile() / fpassthru() (零記憶體複製)
├─ 需要在 PHP 中處理內容
│ ├─ 檔案 < 10MB 且記憶體充足
│ │ └─ file_get_contents() (最簡潔、效能佳)
│ ├─ 大檔案 / 記憶體受限 / 逐行處理
│ │ └─ fopen() + fgets()/fread() (流式處理)
│ ├─ 二進位檔 / 隨機存取 / 精確位移
│ │ └─ fopen('rb') + fseek() + fread()
│ └─ INI 格式設定檔
│ └─ parse_ini_file()
└─ 遠端 HTTP 資源
└─ file_get_contents() + stream_context (簡單)
或 cURL (複雜認證/重試/並發)
fopen($file, 'rb') 確保跨平台相容 (Windows CRLF)$handle = @fopen(...); if (!$handle) throw new Exception(...)try { ... } finally { fclose($handle); }allow_url_fopen=On (php.ini),生產環境建議關閉改用 cURLfopen(urlencode($path), 'r')memory_get_peak_usage() 驗證理解 8 種讀取方法的定位差異,能根據檔案大小、處理需求、記憶體限制選擇最佳方案,避免 OOM 與效能陷阱。