[PHP]fprintf関数完全解説:フォーマット指定出力で開発効率アップ

PHP

はじめに

PHPでファイル操作を行う際、データを整形して書き込みたいケースは多々あります。そんな時に便利なのがfprintf()関数です。この関数はC言語のprintf系関数に慣れている方には馴染み深いものですが、PHPでも強力な機能を発揮します。今回は、この便利な関数の使い方と実践的な活用法について詳しく解説します。

fprintf関数とは?

fprintf()関数は、フォーマット指定した文字列をファイルストリームに書き込む関数です。基本構文は次のとおりです:

int fprintf(resource $stream, string $format, mixed ...$values)

引数の説明

  • $stream: 書き込み先のファイルポインタ(fopen()などで開いたもの)
  • $format: 書式指定文字列(後述)
  • $values: 書式に従って挿入する値(複数可)

戻り値

  • 書き込みに成功した場合:書き込まれたバイト数
  • 失敗した場合:負の値

基本的な使い方

<?php
// ファイルを書き込みモードで開く
$file = fopen('data.txt', 'w');

// 基本的な使用例
$name = "田中太郎";
$age = 28;
fprintf($file, "名前: %s, 年齢: %d歳\n", $name, $age);

// ファイルを閉じる
fclose($file);
?>

上記のコードを実行すると、data.txtに「名前: 田中太郎, 年齢: 28歳」という内容が書き込まれます。

フォーマット指定子の詳細

fprintf()のパワーは、フォーマット指定子にあります。主な指定子は以下の通りです:

  • %s – 文字列
  • %d – 整数(10進数)
  • %f – 浮動小数点数
  • %c – 1文字
  • %e – 指数形式
  • %u – 符号なし10進数
  • %o – 8進数
  • %x – 16進数(小文字)
  • %X – 16進数(大文字)
  • %% – パーセント記号そのもの

応用的なフォーマット指定

数値の桁数や小数点以下の桁数なども指定できます:

<?php
$file = fopen('report.txt', 'w');

// 小数点以下2桁まで表示
$price = 1234.5678;
fprintf($file, "価格: %.2f円\n", $price); // 「価格: 1234.57円」と出力

// 数値の幅を指定(右寄せ)
fprintf($file, "ID: %5d\n", 42); // 「ID:    42」と出力(先頭に空白)

// 0埋め
fprintf($file, "コード: %04d\n", 7); // 「コード: 0007」と出力

// 左寄せ
fprintf($file, "項目: %-10s次の項目\n", "テスト"); // 「項目: テスト      次の項目」と出力

fclose($file);
?>

実践的な活用例

1. CSVファイルの生成

<?php
function generateCSV($data, $filename) {
    $file = fopen($filename, 'w');

    // ヘッダー行
    fprintf($file, "%s,%s,%s,%s\n", "ID", "名前", "メールアドレス", "登録日");

    // データ行
    foreach ($data as $row) {
        fprintf($file, "%d,\"%s\",\"%s\",\"%s\"\n", 
                $row['id'], 
                $row['name'], 
                $row['email'], 
                $row['created_at']);
    }

    fclose($file);
    return true;
}

// 使用例
$users = [
    ['id' => 1, 'name' => '山田花子', 'email' => 'yamada@example.com', 'created_at' => '2023-01-15'],
    ['id' => 2, 'name' => '鈴木一郎', 'email' => 'suzuki@example.com', 'created_at' => '2023-02-20']
];
generateCSV($users, 'users.csv');
?>

2. ログファイルの作成

<?php
function writeLog($message, $level = 'INFO') {
    $logFile = fopen('application.log', 'a');
    $timestamp = date('Y-m-d H:i:s');

    fprintf($logFile, "[%s] %-7s - %s\n", 
            $timestamp, 
            $level, 
            $message);

    fclose($logFile);
}

// 使用例
writeLog('ユーザーがログインしました', 'INFO');
writeLog('データベース接続エラー', 'ERROR');
writeLog('新規アカウントが作成されました', 'INFO');
?>

出力結果:

[2023-03-10 14:22:31] INFO    - ユーザーがログインしました
[2023-03-10 14:22:31] ERROR   - データベース接続エラー
[2023-03-10 14:22:31] INFO    - 新規アカウントが作成されました

3. 設定ファイルの動的生成

<?php
function generateConfigFile($settings, $filename) {
    $file = fopen($filename, 'w');

    fprintf($file, "# 設定ファイル\n");
    fprintf($file, "# 生成日時: %s\n\n", date('Y-m-d H:i:s'));

    foreach ($settings as $section => $values) {
        fprintf($file, "[%s]\n", $section);

        foreach ($values as $key => $value) {
            if (is_bool($value)) {
                $value = $value ? 'true' : 'false';
            } elseif (is_string($value)) {
                $value = "\"$value\"";
            }

            fprintf($file, "%-20s = %s\n", $key, $value);
        }

        fprintf($file, "\n");
    }

    fclose($file);
}

// 使用例
$config = [
    'database' => [
        'host' => 'localhost',
        'user' => 'dbuser',
        'password' => 'secret',
        'port' => 3306,
        'use_ssl' => true
    ],
    'application' => [
        'debug_mode' => true,
        'log_level' => 'info',
        'cache_time' => 3600
    ]
];

generateConfigFile($config, 'config.ini');
?>

fprintf vs. fputs/fwrite

fprintf()と同様に、PHPではfputs()fwrite()のエイリアス)も使用可能です。これらの違いは:

<?php
$file = fopen('test.txt', 'w');

// fwriteの場合:単純な文字列書き込み
$name = "鈴木";
$age = 30;
fwrite($file, "名前: $name, 年齢: $age\n");

// fprintfの場合:フォーマット指定付き書き込み
fprintf($file, "名前: %s, 年齢: %d\n", $name, $age);

fclose($file);
?>

違いのポイント:

  • fwrite()/fputs():変数展開を用いた単純な文字列書き込み
  • fprintf():フォーマット指定子を使った柔軟な書式設定が可能

sprintf, vsprintf, vfprintf との関係

PHPにはfprintf()の他にも類似関数があります:

  • sprintf():ファイルに書き込まず、フォーマットした文字列を返す
  • vsprintf():値を配列で受け取るsprintf()
  • vfprintf():値を配列で受け取るfprintf()
<?php
// sprintfの例
$formatted = sprintf("ID: %04d, 名前: %s", 42, "佐藤");
echo $formatted; // "ID: 0042, 名前: 佐藤"

// vfprintfの例
$file = fopen('data.txt', 'w');
$values = [42, "佐藤"];
vfprintf($file, "ID: %04d, 名前: %s\n", $values);
fclose($file);
?>

パフォーマンスと注意点

1. エラーハンドリング

<?php
$file = fopen('data.txt', 'w');
if ($file === false) {
    die("ファイルを開けませんでした");
}

$bytes = fprintf($file, "テストデータ: %s\n", "サンプル");
if ($bytes === false) {
    die("書き込みに失敗しました");
}

echo "$bytes バイト書き込みました";
fclose($file);
?>

2. 特殊文字のエスケープ

フォーマット文字列にユーザー入力を直接使うことは避けましょう。特殊文字(%など)が含まれているとフォーマット指定子として解釈されてしまいます。

<?php
$file = fopen('data.txt', 'w');

// 安全な使い方
$userInput = "テスト 50% 完了";
fprintf($file, "状態: %s\n", $userInput);

// ユーザー入力をフォーマット文字列として使うのは危険
// fprintf($file, $userInput, $someValue); // 避けるべき

fclose($file);
?>

まとめ

PHPのfprintf()関数は、整形されたデータをファイルに書き込む際の強力なツールです。特に:

  • 複雑なフォーマットが必要な場合
  • 数値の表示形式を制御したい場合
  • ログファイル、設定ファイル、レポートなどを生成する場合

に非常に便利です。fwrite()と比較して若干のオーバーヘッドがありますが、可読性と保守性の向上というメリットがあります。ぜひPHPでのファイル操作の際に活用してみてください。

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