[PHP]file_put_contents関数の完全ガイド – ファイル書き込みのベストプラクティス

PHP

こんにちは!PHPでファイル書き込みを行うfile_put_contents関数について、基本から実践的な使い方まで詳しく解説します。

1. 基本的な使い方

// 単純な文字列の書き込み
file_put_contents('sample.txt', 'Hello World!');

// 配列の書き込み
$data = ['line1', 'line2', 'line3'];
file_put_contents('array.txt', implode("\n", $data));

2. フラグオプションの活用

2-1. ファイルへの追記(FILE_APPEND)

// 既存のファイルに追記
file_put_contents(
    'log.txt',
    date('Y-m-d H:i:s') . ': ログメッセージ' . PHP_EOL,
    FILE_APPEND
);

2-2. 排他的ロック(LOCK_EX)

// 排他的ロックを使用して安全に書き込み
file_put_contents(
    'important.txt',
    'クリティカルなデータ',
    LOCK_EX
);

// 複数のフラグを組み合わせる
file_put_contents(
    'log.txt',
    'ログエントリ' . PHP_EOL,
    FILE_APPEND | LOCK_EX
);

3. 実践的な使用例

3-1. JSONデータの保存

function saveJsonData($filename, $data) {
    try {
        $jsonData = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        if ($jsonData === false) {
            throw new Exception('JSONエンコードに失敗しました: ' . json_last_error_msg());
        }

        $result = file_put_contents($filename, $jsonData, LOCK_EX);
        if ($result === false) {
            throw new Exception('ファイルの書き込みに失敗しました');
        }

        return true;
    } catch (Exception $e) {
        error_log($e->getMessage());
        return false;
    }
}

// 使用例
$config = [
    'database' => [
        'host' => 'localhost',
        'user' => 'root'
    ],
    'debug' => true
];
saveJsonData('config.json', $config);

3-2. ログ機能の実装

class Logger {
    private $logFile;

    public function __construct($logFile) {
        $this->logFile = $logFile;
    }

    public function log($message, $level = 'INFO') {
        $logEntry = sprintf(
            "[%s] [%s] %s%s",
            date('Y-m-d H:i:s'),
            $level,
            $message,
            PHP_EOL
        );

        return file_put_contents(
            $this->logFile,
            $logEntry,
            FILE_APPEND | LOCK_EX
        );
    }

    public function clear() {
        return file_put_contents($this->logFile, '');
    }
}

// 使用例
$logger = new Logger('app.log');
$logger->log('アプリケーション開始');
$logger->log('エラーが発生しました', 'ERROR');

3-3. CSVデータの保存

function saveCSV($filename, array $data) {
    $handle = fopen('php://temp', 'r+');

    foreach ($data as $row) {
        fputcsv($handle, $row);
    }

    rewind($handle);
    $csvContent = stream_get_contents($handle);
    fclose($handle);

    return file_put_contents($filename, $csvContent, LOCK_EX);
}

// 使用例
$data = [
    ['名前', '年齢', '都市'],
    ['山田太郎', 30, '東京'],
    ['鈴木花子', 25, '大阪']
];
saveCSV('users.csv', $data);

4. セキュリティ対策

4-1. 安全なファイル書き込み

function secureFilePut($filename, $content) {
    // ディレクトリトラバーサル対策
    $filename = basename($filename);
    $safePath = __DIR__ . '/allowed_directory/' . $filename;

    // ディレクトリの存在確認
    $directory = dirname($safePath);
    if (!file_exists($directory)) {
        mkdir($directory, 0755, true);
    }

    // パーミッションチェック
    if (file_exists($safePath) && !is_writable($safePath)) {
        throw new Exception('ファイルに書き込み権限がありません');
    }

    return file_put_contents($safePath, $content, LOCK_EX);
}

4-2. バックアップの作成

function saveWithBackup($filename, $content) {
    // 既存ファイルのバックアップ
    if (file_exists($filename)) {
        $backupName = $filename . '.' . date('Y-m-d-His') . '.bak';
        copy($filename, $backupName);
    }

    // 新しい内容を書き込み
    return file_put_contents($filename, $content, LOCK_EX);
}

5. エラーハンドリング

function robustFilePut($filename, $content) {
    try {
        // ディスク容量チェック
        $requiredSpace = strlen($content);
        $freeSpace = disk_free_space(dirname($filename));

        if ($freeSpace < $requiredSpace) {
            throw new Exception('ディスク容量が不足しています');
        }

        // 書き込み試行
        $result = file_put_contents($filename, $content, LOCK_EX);
        if ($result === false) {
            throw new Exception('ファイルの書き込みに失敗しました');
        }

        // 書き込み確認
        clearstatcache(true, $filename);
        if (filesize($filename) !== strlen($content)) {
            throw new Exception('書き込みサイズが一致しません');
        }

        return true;

    } catch (Exception $e) {
        error_log($e->getMessage());
        return false;
    }
}

まとめ

file_put_contents関数を使用する際は、以下の点に注意しましょう:

  1. 適切なフラグ(FILE_APPEND, LOCK_EX)の使用
  2. エラーハンドリングの実装
  3. セキュリティ対策の考慮
  4. バックアップ戦略の検討
  5. パーミッションの確認

これらの点を意識することで、より安全で信頼性の高いファイル操作が実現できます。

タイトルとURLをコピーしました