雖然 PHP 內建 copy() 函數簡單好用,但在某些受限環境(如禁用特定函數、需自定義緩衝邏輯、或處理超大檔案分塊讀寫)下,掌握「讀取→寫入」的底層邏輯至關重要。本文示範如何用 file_get_contents、fopen、fwrite 組合實現檔案複製。
<?php
function copyFileManual(string $source, string $dest): bool
{
// 1. 讀取來源檔案內容
$content = @file_get_contents($source);
if ($content === false) {
return false; // 讀取失敗
}
// 2. 以寫入模式開啟目標檔案(不存在則建立,存在則截斷)
$handle = @fopen($dest, 'wb');
if (!$handle) {
return false; // 無法開啟寫入
}
// 3. 寫入內容
$bytesWritten = fwrite($handle, $content);
fclose($handle);
// 4. 驗證寫入位元組數
return $bytesWritten === strlen($content);
}
// 使用範例
if (copyFileManual('data/source.txt', 'data/backup.txt')) {
echo "複製成功";
} else {
echo "複製失敗";
}
?>
一次性讀取巨大檔案會耗盡記憶體。使用串流分塊處理更安全:
<?php
function copyFileStream(string $source, string $dest, int $bufferSize = 8192): bool
{
$srcHandle = @fopen($source, 'rb');
$destHandle = @fopen($dest, 'wb');
if (!$srcHandle || !$destHandle) {
if ($srcHandle) fclose($srcHandle);
if ($destHandle) fclose($destHandle);
return false;
}
while (!feof($srcHandle)) {
$chunk = fread($srcHandle, $bufferSize);
if ($chunk === false) break;
if (fwrite($destHandle, $chunk) === false) {
fclose($srcHandle);
fclose($destHandle);
return false;
}
}
fclose($srcHandle);
fclose($destHandle);
return true;
}
?>
| 函數 | 用途 | 模式說明 |
|---|---|---|
file_get_contents | 一次讀取整個檔案到字串 | 簡單、小檔案適用 |
fopen($file, 'rb') | 以二進位唯讀模式開啟 | 'r'=讀取, 'b'=二進位(跨平台安全) |
fopen($file, 'wb') | 以二進位寫入模式開啟 | 'w'=寫入(截斷/建立), 'b'=二進位 |
fread($handle, $len) | 從控制代碼讀取指定長度 | 配合 feof() 迴圈分塊讀取 |
fwrite($handle, $data) | 寫入資料到控制代碼 | 回傳寫入位元組數,需檢查是否完整 |
@ 抑制警告,改用回傳值判斷成功與否。=== false 嚴格比較,避免 0 或空字串被誤判。fclose() 釋放資源,建議搭配 try-finally 或註冊關閉函數。掌握手動複製邏輯,不僅能應對受限環境,更能深入理解 PHP 檔案 I/O 機制,為處理大檔案、網路串流、加密寫入等進階場景打下基礎。