| 模式 | 讀/寫 | 指標 | 建立 | 截斷 | 失敗行為 |
|---|---|---|---|---|---|
| r | 讀 | 開頭 | 否 | 否 | false |
| r+ | 讀/寫 | 開頭 | 否 | 否 | false |
| w | 寫 | 開頭 | 是 | 是 | false |
| w+ | 讀/寫 | 開頭 | 是 | 是 | false |
| a | 寫 | 結尾 | 是 | 否 | false |
| a+ | 讀/寫 | 結尾 | 是 | 否 | false |
| x | 寫 | 開頭 | 唯不存在 | 否 | false |
| x+ | 讀/寫 | 開頭 | 唯不存在 | 否 | false |
<?php
// 手動管理
$fp = fopen('data.txt', 'r');
if ($fp) {
try {
// 讀取邏輯
} finally {
fclose($fp); // 確保關閉
}
}
// PHP 8.1+ 可用 fclose 自動管理(但 fopen 無支援)
// 建議封裝函數
function withFile(string $path, string $mode, callable $callback) {
$fp = fopen($path, $mode);
if (!$fp) throw new RuntimeException("無法開啟 $path");
try {
return $callback($fp);
} finally {
fclose($fp);
}
}
// 使用
$content = withFile('data.txt', 'r', fn($fp) => stream_get_contents($fp));
?>
<?php
function hitCounter(string $file = 'counter.txt'): int {
$count = 0;
if (file_exists($file)) {
$count = (int) file_get_contents($file);
}
$count++;
file_put_contents($file, $count, LOCK_EX); // 獨佔鎖防並發
return $count;
}
echo "您是第 " . hitCounter() . " 位訪客";
?>
<?php
// robots_editor.php
$file = __DIR__ . '/robots.txt';
$action = $_GET['action'] ?? 'view';
$message = '';
if ($action === 'save' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$content = $_POST['content'] ?? '';
if (file_put_contents($file, $content, LOCK_EX) !== false) {
$message = '儲存成功';
} else {
$message = '儲存失敗';
}
}
$content = file_exists($file) ? file_get_contents($file) : '';
?>
<!DOCTYPE html>
<html><head><title>robots.txt 編輯器</title></head><body>
<h1>robots.txt</h1>
= htmlspecialchars($message) ?>
</body></html>
<?php
function processLargeFile(string $path, callable $lineHandler): void {
$fp = fopen($path, 'r');
if (!$fp) throw new RuntimeException("無法開啟 $path");
while (($line = fgets($fp)) !== false) {
$lineHandler(rtrim($line, "\r\n"));
}
fclose($fp);
}
// 使用
processLargeFile('huge.log', function($line) {
if (str_contains($line, 'ERROR')) {
error_log($line);
}
});
?>
LOCK_EX 獨佔鎖(寫入時)LOCK_SH 共享鎖(讀取時)file_put_contents(..., LOCK_EX) 內建支援flock($fp, LOCK_EX) 手動控制