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

PHP 讀取檔案 8 種方法完整對比:fread、fgets、file、file_get_contents 效能與適用場景

     編輯:PHP 綜合知識

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

詳細用法與範例

1. fread() - 精確位元組控制

// 讀取整個檔案 (小檔案)
$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);

2. fgets() / fgetss() - 逐行處理

$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);

3. file() - 陣列化全量載入

$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";
}

4. readfile() - 直接輸出下載

// 圖片/檔案下載輸出
header('Content-Type: image/jpeg');
header('Content-Disposition: attachment; filename="photo.jpg"');
header('Content-Length: ' . filesize('photo.jpg'));
readfile('photo.jpg'); // 直接輸出到瀏覽器,不佔 PHP 記憶體
exit;

5. file_get_contents() - 現代首選 (含 HTTP)

// 本地檔案
$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);

6. fpassthru() - 已開啟資源輸出

$handle = fopen('video.mp4', 'rb');
fseek($handle, 1024 * 1024); // 跳過前 1MB
fpassthru($handle); // 輸出剩餘內容到瀏覽器
fclose($handle);

7. parse_ini_file() - 設定檔解析

// 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]
]
*/

效能基準測試 (100MB 檔案)

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); }
  • URL 開啟:allow_url_fopen=On (php.ini),生產環境建議關閉改用 cURL
  • 特殊字元路徑:fopen(urlencode($path), 'r')
  • 記憶體監控:大檔案用 memory_get_peak_usage() 驗證

理解 8 種讀取方法的定位差異,能根據檔案大小、處理需求、記憶體限制選擇最佳方案,避免 OOM 與效能陷阱。

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